home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / rxdoscmd.zip / RXDOSCMD.ASM < prev    next >
Assembly Source File  |  1993-06-06  |  233KB  |  5,445 lines

  1.         TITLE   'Cmd - RxDOS Command Shell'
  2.         PAGE 59, 132
  3.         .LALL
  4.  
  5.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  6.         ;  RxDOS Command Shell                                          ;
  7.         ;...............................................................;
  8.  
  9.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  10.         ;  Real Time Dos                                                ;
  11.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  12.         ;                                                               ;
  13.         ;  This material  was created as a published version  of a DOS  ;
  14.         ;  equivalent product.   This program  logically  functions in  ;
  15.         ;  the same way as  MSDOS functions and it  is  internal  data  ;
  16.         ;  structure compliant with MSDOS 5.0                           ;
  17.         ;                                                               ;
  18.         ;  This product is distributed  AS IS and contains no warranty  ;
  19.         ;  whatsoever,   including  warranty  of   merchantability  or  ;
  20.         ;  fitness for a particular purpose.                            ;
  21.         ;                                                               ;
  22.         ;                                                               ;
  23.         ;  (c) Copyright 1990, 1992. Api Software and Mike Podanoffsky  ;
  24.         ;      All Rights Reserved Worldwide.                           ;
  25.         ;                                                               ;
  26.         ;  This product is protected under copyright laws and  may not  ;
  27.         ;  be reproduced  in whole  or in part, in any form  or media,  ;
  28.         ;  included but not limited to source listing, facimilie, data  ;
  29.         ;  transmission, cd-rom, or  floppy disk without the expressed  ;
  30.         ;  written consent of the author.                               ;
  31.         ;                                                               ;
  32.         ;  Licence for distribution in commercial use:                  ;
  33.         ;                                                               ;
  34.         ;  Api Software                                                 ;
  35.         ;  12 South Walker Street                                       ;
  36.         ;  Lowell,  MA   01851                                          ;
  37.         ;  508/ 454-4961.                                               ;
  38.         ;                                                               ;
  39.         ;...............................................................;
  40.  
  41.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  42.         ;  RxDOS Command Shell                                          ;
  43.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  44.         ;                                                               ;
  45.         ;  Programmer's Notes:                                          ;
  46.         ;                                                               ;
  47.         ;  Command Shell consists of  two parts bound  together into a  ;
  48.         ;  single executable load.  There  exists  a  single  resident  ;
  49.         ;  command shell which is accessible by an Int 2Eh.             ;
  50.         ;                                                               ;
  51.         ;...............................................................;
  52.  
  53.         include rxdosmac.asm
  54.         include rxdosdef.asm
  55.         include rxdoscin.asm
  56.  
  57.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  58.         ;  Execution Control                                            ;
  59.         ;...............................................................;
  60.  
  61.         EXECCONTROL struc
  62.  
  63. exCtrlArgArray                  dd ?
  64. exCtrlStdInHandle               dw ?
  65. exCtrlStdOutHandle              dw ?
  66.  
  67. exCtrlFlags                     dw ?
  68. exCtrlLoadExecBlock             db sizeLOADEXEC dup(?)
  69.  
  70.         EXECCONTROL ends
  71.  
  72. exCtrlPiped                     equ 8000h
  73. exCtrlAppend                    equ 4000h               ; append to stdout
  74.  
  75. sizeEXECCONTROL                 equ size EXECCONTROL
  76.  
  77. _BAT                            equ 0
  78. _EXE                            equ 1
  79. _COM                            equ 2
  80.  
  81.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  82.         ;  If Special Values                                            ;
  83.         ;...............................................................;
  84.  
  85. IF_NOT                          equ 01h
  86. IF_ERRORLEVEL                   equ 02h
  87. IF_EXIST                        equ 03h
  88.  
  89. _ARGTEXT                        equ _high
  90. _ARGTYPE                        equ _low
  91.  
  92.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  93.         ;  RxDOS Command Shell                                          ;
  94.         ;...............................................................;
  95.  
  96.         public CommandBegin
  97.  
  98. RxDOSCMD SEGMENT PUBLIC 'CODE'
  99.          assume cs:RxDOSCMD, ds:RxDOSCMD, es:RxDOSCMD, ss:RxDOSCMD
  100.  
  101.         org 100h
  102.  
  103.         public CheckOptOneArg
  104.         public CmndError_BadSwitch
  105.         public CmndError_CannotCopyUntoSelf
  106.         public CmndError_CannotCreateFile
  107.         public CmndError_ContentsLostBeforeCopy
  108.         public CmndError_FileAlreadyExists
  109.         public CmndError_FileNotFound
  110.         public CmndError_InvalidDate
  111.         public CmndError_InvalidDrive
  112.         public CmndError_InvalidTime
  113.         public CmndError_NoFilesFound
  114.         public CmndError_SyntaxError
  115.  
  116.         public CRLF
  117.         public CmndLookup
  118.         public _Copy_FilesCopied
  119.         public CountArgs
  120.  
  121.         public deleteArg
  122.         public deleteEnvVariable
  123.         public DisplayError
  124.         public DisplayErrorMessage
  125.         public DisplayLine
  126.         public insertEnvVariable
  127.         public PreProcessCmndLine
  128.         public ReplaceForVariables
  129.         public returnVolumeName
  130.         public searchEnvVariable
  131.         public setPagingMode
  132.  
  133.         public RxDOSIntl_DateTemplate
  134.         public RxDOSIntl_DayOfWeek
  135.         public RxDOSIntl_TimeTemplate
  136.         public RxDOSIntl_DateTimeTable
  137.  
  138.         public RxDOS_AllFiles
  139.         public RxDOS_DefaultPrompt
  140.         public RxDOS_DTA
  141.         public RxDOS_ForArgs
  142.         public RxDOS_Prompt
  143.         public RxDOS_PromptSpec
  144.         public RxDOS_Version
  145.  
  146.         public _AppendPathName
  147.         public _CmndParse_Break
  148.         public _CopyString
  149.         public _DirAttribSwitch
  150.         public _DirBareSwitch
  151.         public _DirLowerCaseSwitch
  152.         public _DirOrderSwitch
  153.         public _DirPauseSwitch
  154.         public _DirSubDirSwitch
  155.         public _DirSwitches
  156.         public _DirWideSwitch
  157.         public _Dir_DirectoryOf
  158.         public _Dir_DirEntry
  159.         public _Dir_FileEntry
  160.         public _Dir_Files
  161.         public _Dir_NoVolumeLabel
  162.         public _Dir_VolumeLabel
  163.         public _Dir_VolumeSerialNumber
  164.         public _endofString
  165.         public _EnvSegment
  166.         public _GetNumber
  167.         public _getStdinLine
  168.         public _InternalCommandParser
  169.         public _lowerCase
  170.         public _lowerCaseString
  171.         public _PleaseEnterDate
  172.         public _PleaseEnterTime
  173.         public _ShowCurrentDate
  174.         public _ShowCurrentTime
  175.         public _sprintf
  176.         public _SwitchChar
  177.  
  178.     ; in rxdoscpy.asm
  179.  
  180.         extrn _Copy                                     : near
  181.  
  182.     ; in rxdosdir.asm
  183.  
  184.         extrn _Dir                                      : near
  185.  
  186.     ; in rxdosfor.asm
  187.  
  188.         extrn _For                                      : near
  189.  
  190.     ; in rxdosprm.asm
  191.  
  192.         extrn _Prompt                                   : near
  193.         extrn _Date                                     : near
  194.         extrn _Time                                     : near
  195.  
  196.         extrn DisplayPrompt                             : near
  197.         extrn formatCurrentDate                         : near
  198.         extrn formatCurrentTime                         : near
  199.  
  200.     ; in rxdosren.asm
  201.  
  202.         extrn _Rename                                   : near
  203.  
  204.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  205.         ;  RxDOS Command Parser/ Execute                                ;
  206.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  207.         ;                                                               ;
  208.         ;  Usage:                                                       ;
  209.         ;   ds:si  command line beginning with a count                  ;
  210.         ;          (this fct does not rely on CR at end of buffer)      ;
  211.         ;                                                               ;
  212.         ;   The command is executed, which may require loading another  ;
  213.         ;   program.                                                    ;
  214.         ;                                                               ;
  215.         ;   ** MSDOS Difference **                                      ;
  216.         ;                                                               ;
  217.         ;   Unlike MSDOS, this module will preserve all registers.      ;
  218.         ;...............................................................;
  219.  
  220. _InternalCommandParser  proc far
  221.  
  222.         Entry
  223.         def _commandLine, si                            ; argument is copied
  224.         defwords __argarray, 64                         ; 64 arguments
  225.                                                         ; (last arg is null)
  226.         SaveAllRegisters                                ; save all registers
  227.  
  228. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  229. ;  get switch character
  230. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  231.  
  232.         setDS ss
  233.         setES ss
  234.         Int21 GetSetSwitchChar, 00                      ; get switch char        
  235.         mov byte ptr [ _SwitchChar ], dl                ; save switch character
  236.  
  237. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  238. ;  parse
  239. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  240.  
  241.         getarg si, _commandLine
  242.         lea di, offset [ __argarray   ][ bp ]
  243.         call _BuildArgArray                             ; break up into arg list
  244.         jz _intCommandParser_36                         ; if no arguments -->
  245.  
  246.         mov si, word ptr [ __argarray ][ bp ]           ; get lead argument
  247.         cmp byte ptr [ si ], ':'                        ; label line ?
  248.         jz _intCommandParser_36                         ; ignore -->
  249.  
  250.         lea di, offset [ __argarray   ][ bp ]
  251.         call _executeCommandArray
  252.         
  253.         cmp byte ptr [ _EchoStatus ], false             ; echo ?
  254.         jz _intCommandParser_36                         ; if no echo -->
  255.         call CRLF
  256.  
  257. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  258. ;  command completed
  259. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  260.  
  261. _intCommandParser_36:
  262.         restoreAllRegisters
  263.         mov sp, bp
  264.         pop bp                                          ; restore bp
  265.         ret
  266.  
  267. _InternalCommandParser  endp
  268.  
  269.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  270.         ;  RxDOS Command Parser/ Execute                                ;
  271.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  272.         ;                                                               ;
  273.         ;  Usage:                                                       ;
  274.         ;   ds:si  command line beginning with a count                  ;
  275.         ;          (this fct does not rely on CR at end of buffer)      ;
  276.         ;                                                               ;
  277.         ;   The command is executed, which may require loading another  ;
  278.         ;   program.                                                    ;
  279.         ;                                                               ;
  280.         ;   ** MSDOS Difference **                                      ;
  281.         ;                                                               ;
  282.         ;   Unlike MSDOS, this module will preserve all registers.      ;
  283.         ;...............................................................;
  284.  
  285. _CommandParser  proc far
  286.  
  287.         Entry
  288.         defbytes _commandLine, 128                      ; argument is copied
  289.                                                         ; (last arg is null)
  290.         SaveAllRegisters                                ; save all registers
  291.         sti
  292.  
  293. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  294. ;  copy command line 
  295. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  296.  
  297.         lodsb 
  298.         mov cl, al                                      ; length
  299.         xor ch, ch
  300.         or cx, cx
  301.         jz _commandParser_36                            ; if no arguments -->
  302.  
  303.         setES ss
  304.         lea di, offset [ _commandLine ][ bp ]
  305.         rep movsb                                       ; copy command line
  306.         
  307.         xor ax, ax
  308.         stosb                                           ; add a null terminator
  309.  
  310. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  311. ;  parse line
  312. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  313.  
  314.         lea si, offset [ _commandLine ][ bp ]
  315.         call _InternalCommandParser
  316.  
  317. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  318. ;  command completed
  319. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  320.  
  321. _commandParser_36:
  322.         restoreAllRegisters
  323.         mov sp, bp
  324.         pop bp                                          ; restore bp
  325.         iret
  326.  
  327. _CommandParser  endp
  328.  
  329.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  330.         ;  Execute Command Stored in Arg Array                          ;
  331.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  332.         ;                                                               ;
  333.         ;  Usage:                                                       ;
  334.         ;   ss:di  argument array                                       ;
  335.         ;...............................................................;
  336.  
  337. _executeCommandArray:
  338.  
  339.         Entry
  340.         def __argarray, di                              ; argument array
  341.         defbytes __execCtrlBlock, sizeEXECCONTROL
  342.  
  343. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  344. ;  scan remainder of command line for pipe, stdin and stdout args
  345. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  346.  
  347.         xor ax, ax
  348.         lea bx, offset [ __execCtrlBlock ][ bp ]
  349.  
  350.         push di
  351.         mov di, bx
  352.         mov cx, sizeEXECCONTROL
  353.         rep stosb                                       ; clear exec control block
  354.         pop di
  355.  
  356.         mov dx, -1
  357.         mov word ptr [ exCtrlStdOutHandle ][ bx ], dx   ; no stdout file
  358.         mov word ptr [ exCtrlStdInHandle ][ bx ], dx    ; no stdin file
  359.  
  360. _executeArray_04:
  361.         lea bx, offset [ __execCtrlBlock ][ bp ]
  362.         call _assignRedirectedDevices                   ; arg array in [di]
  363.  
  364. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  365. ;  see if command is valid
  366. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  367.  
  368.         mov si, word ptr [ di ]                         ; get lead argument
  369.         mov di, offset RxDOS_InternalCommands
  370.         call CmndLookup                                 ; lookup command
  371.         jnc _executeArray_26                            ; if command found -->
  372.  
  373. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  374. ;  see if valid drive letter
  375. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  376.  
  377.         mov di, word ptr [ __argarray ][ bp ]           ; arguments pointer
  378.         mov si, word ptr [ di ]                         ; get lead argument
  379.         cmp word ptr ss:[ si+1 ], ':'                   ; disk select ?
  380.         jnz _executeArray_12                            ; if unknown -->
  381.  
  382.         call CountArgs                                  ; count how many arguments
  383.         call _DiskSelect                                ; process disk select
  384.         jmp _executeArray_36
  385.  
  386. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  387. ;  see if .exe, .com, or .bat 
  388. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  389.  
  390. _executeArray_12:
  391.         call _executeProgram                            ; try to execute program
  392.         jmp _executeArray_36
  393.         
  394. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  395. ;  go process command
  396. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  397.  
  398. _executeArray_26:
  399.         mov di, word ptr [ __argarray ][ bp ]           ; arguments pointer
  400.         call SplitArgs                                  ; for cd.. cases
  401.  
  402.         inc di
  403.         inc di                                          ; argument array past arg 
  404.         mov si, word ptr [ di ]                         ; get lead argument
  405.         call CountArgs                                  ; count how many arguments
  406.         call bx                                         ; go execute commands
  407.  
  408. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  409. ;  done
  410. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  411.  
  412. _executeArray_36:
  413.         mov byte ptr [ PageLines ], 00                  ; cancel page lines
  414.  
  415.         mov bx, STDIN
  416.         mov ax, word ptr [ __execCtrlBlock. exCtrlStdInHandle ][ bp ]
  417.         call _CloseRedirectedDevice
  418.  
  419. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  420. ;  is arg piped ?
  421. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  422.  
  423.         getarg di, __argarray
  424.         test word ptr [ __execCtrlBlock. exCtrlFlags ][ bp ], exCtrlPiped
  425.         jnz _executeArray_38
  426.  
  427.         mov bx, STDOUT
  428.         mov ax, word ptr [ __execCtrlBlock. exCtrlStdOutHandle ][ bp ]
  429.         call _CloseRedirectedDevice
  430.         Return
  431.  
  432. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  433. ;  arg is piped
  434. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  435.  
  436. _executeArray_38:
  437.         mov ax, word ptr [ di ]
  438.         inc di
  439.         inc di
  440.         or ax, ax                                       ; at end of search ?
  441.         jnz _executeArray_38                            ; keep loopking -->
  442.  
  443. _executeArray_42:
  444.         and word ptr [ __execCtrlBlock. exCtrlFlags ][ bp ], NOT exCtrlPiped
  445.         storarg __argarray, di                          ; next in arg array
  446.  
  447.     ; must reopen file given by temp...
  448.     ; maybe should not have closed it.
  449.  
  450.         mov cx, STDOUT
  451.         call _assignGetCurrHandle                       ; get current handle
  452.         mov word ptr [ __execCtrlBlock. exCtrlStdInHandle ][ bp ], ax
  453.  
  454.         mov bx, STDOUT
  455.         Int21 CommitFile                                ; close stdout
  456.  
  457.         xor cx, cx
  458.         xor dx, dx
  459.         mov bx, STDOUT
  460.         Int21 MoveFilePointer, SEEK_BEG                 ; point to beg of file
  461.  
  462.         mov bx, STDOUT
  463.         mov cx, STDIN
  464.         Int21 ForceFileHandle                           ; redirect stdout -> stdin
  465.  
  466.         mov bx, STDOUT
  467.         mov ax, word ptr [ __execCtrlBlock. exCtrlStdOutHandle ][ bp ]
  468.         call _CloseRedirectedDevice
  469.  
  470.         getarg di, __argarray                           ; next in arg array
  471.         jmp _executeArray_04
  472.  
  473.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  474.         ;  Build Argument Array                                         ;
  475.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  476.         ;                                                               ;
  477.         ;  Usage:                                                       ;
  478.         ;   ds:si  command line beginning with a count                  ;
  479.         ;          (this fct does not rely on CR at end of buffer)      ;
  480.         ;   ss:di  argument array                                       ;
  481.         ;          (returns a pointer into the command line at the      ;
  482.         ;           start of each argument.  Multiple switches are      ;
  483.         ;           detected by testing the get command switch char).   ;
  484.         ;                                                               ;
  485.         ;  Returns:                                                     ;
  486.         ;   zr     if no arguments passed                               ;
  487.         ;...............................................................;
  488.  
  489. _BuildArgArray:
  490.  
  491.         Entry
  492.         ddef _commandLine, ds, si
  493.         ddef __argarray, ss, di                         ; 64 arguments
  494.         def _insideString, 0000                         ; not inside string (yet)
  495.  
  496.         setES ss
  497.         mov word ptr ss:[ di ], 0000                    ; add null table terminator
  498.         mov word ptr ss:[ di+2 ], 0000                  ; two nulls is complete end
  499.         xor cx, cx                                      ; set record flag
  500.  
  501. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  502. ;  scan argument
  503. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  504.  
  505. _buildArgArray_08:
  506.         lodsb                                           ; get character
  507.         or al, al                                       ; end of line ?
  508.         jz _buildArgArray_36                            ; yes, end of arg -->
  509.  
  510.         cmp al, ' '                                     ; space ?
  511.         jz _buildArgArray_26                            ; yes, end of arg -->
  512.  
  513.         cmp al, byte ptr [ _SwitchChar ]                ; switch character ?
  514.         jz _buildArgArray_14                            ; yes, end of arg -->
  515.         call _CmndParse_Break                           ; parse break ?
  516.         jz _buildArgArray_18                            ; yes, test and record -->
  517.  
  518.         or cx, cx                                       ; record flag ?
  519.         jnz _buildArgArray_08                           ; no, scan -->
  520.  
  521. _buildArgArray_14:
  522.         mov ax, si
  523.         dec ax
  524.         stosw                                           ; store pointer to argument
  525.         mov word ptr ss:[ di ], 0000                    ; add null table terminator
  526.         mov word ptr ss:[ di+2 ], 0000                  ; two nulls is complete end
  527.         mov cx, -1                                      ; no need to re-record
  528.  
  529.         jmp _buildArgArray_08                           ; go scan
  530.  
  531. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  532. ;  special arg
  533. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  534.  
  535. _buildArgArray_18:
  536.         cmp al, singleQuote
  537.         jz _buildArgArray_30
  538.         cmp al, doubleQuote
  539.         jz _buildArgArray_30
  540.  
  541. _buildArgArray_22:
  542.         cmp byte ptr [ _insideString ][ bp ], 00        ; inside string ?
  543.         jnz _buildArgArray_08                           ; skip testing for the items below
  544.  
  545.         mov ax, si
  546.         dec ax
  547.         stosw                                           ; store pointer to argument
  548.         mov word ptr ss:[ di ], 0000                    ; add null table terminator
  549.         mov word ptr ss:[ di+2 ], 0000                  ; two nulls is complete end
  550.  
  551. _buildArgArray_26:
  552.         xor cx, cx                                      ; set record flag
  553.         jmp _buildArgArray_08                           ; scan start
  554.  
  555. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  556. ;  set inside string mode
  557. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  558.  
  559. _buildArgArray_30:
  560.         xor ah, ah
  561.         xchg ah, byte ptr [ _insideString ][ bp ]       ; kill inside string mode
  562.         or ah, ah                                       ; was inside string ?
  563.         jnz _buildArgArray_08                           ; yes, continue parsing line -->
  564.  
  565.         mov byte ptr [ _insideString ][ bp ], al        ; else set inside string mode
  566.  
  567.         mov ax, si
  568.         dec ax
  569.         stosw                                           ; store pointer to argument
  570.         mov word ptr ss:[ di ], 0000                    ; add null table terminator
  571.         mov word ptr ss:[ di+2 ], 0000                  ; two nulls is complete end
  572.         mov cx, -1                                      ; no need to record again
  573.         jmp _buildArgArray_08                           ; continue scanning -->
  574.  
  575. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  576. ;  return
  577. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  578.  
  579. _buildArgArray_36:
  580.         mov di, word ptr [ __argarray. _pointer ][ bp ]
  581.         cmp word ptr [ di ], 0000                       ; args passed ?
  582.         Return
  583.  
  584.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  585.         ;  Split Args                                                   ;
  586.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  587.         ;                                                               ;
  588.         ;  Some args are passed in the arg array as a single arg pointer;
  589.         ;  when in fact they need to be split up, as in 'cd..'          ;
  590.         ;                                                               ;
  591.         ;  This routine will fix that.                                  ;
  592.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  593.         ;                                                               ;
  594.         ;  Usage:                                                       ;
  595.         ;   di     pointer to args array                                ;
  596.         ;...............................................................;
  597.  
  598. SplitArgs:
  599.  
  600.         Entry
  601.         def __argarray, di                              ; pointer to args
  602.  
  603.         mov si, word ptr [ di ]                         ; get arg
  604.         or si, si                                       ; args passed ?
  605.         jz _SplitArgs_36                                ; none -->
  606.  
  607. _SplitArgs_08:
  608.         lodsb
  609.         or al, al                                       ; null ?
  610.         jz _SplitArgs_36                                ; end of search -->
  611.         cmp al, ' '+1                                   ; space or other break ?
  612.         jc _SplitArgs_36                                ; end of search -->
  613.         cmp al, '\'                                     ; dir break ?
  614.         jz _SplitArgs_12                                ; yes, insert arg -->
  615.         cmp al, '.'                                     ; period break ?
  616.         jnz _SplitArgs_08                               ; continue if none of the above -->
  617.  
  618. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  619. ;  Insert Arg
  620. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  621.  
  622. _SplitArgs_12:
  623.         mov ax, si                                      ; set arg
  624.         dec ax
  625.  
  626. _SplitArgs_16:
  627.         inc di
  628.         inc di
  629.         xchg ax, word ptr [ di ]                        ; push arg
  630.         or ax, ax                                       ; end of table ?
  631.         jnz _SplitArgs_16                               ; not yet -->
  632.  
  633.         cmp word ptr [ di+2 ], 0000                     ; 2nd null follows ?
  634.         jnz _SplitArgs_16                               ; no, keep inserting -->
  635.  
  636.         mov word ptr [ di+2 ], ax                       ; make sure we put two NULLS
  637.         mov word ptr [ di+4 ], ax                       ; 
  638.  
  639. _SplitArgs_36:
  640.         getarg di, __argarray                           ; pointer to args
  641.         Return
  642.  
  643.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  644.         ;  Command Parse Break                                          ;
  645.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  646.         ;                                                               ;
  647.         ;  Usage:                                                       ;
  648.         ;   al     character from parser                                ;
  649.         ;                                                               ;
  650.         ;  Returns:                                                     ;
  651.         ;   zr     is a break character                                 ;
  652.         ;...............................................................;
  653.  
  654. _CmndParse_Break:
  655.  
  656.         push si
  657.         mov si, offset _CmndParse_Separators 
  658.  
  659. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  660. ;  lookup
  661. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  662.  
  663. _CmndParse_Break_08:
  664.         cmp byte ptr cs:[ si ], 0
  665.         jz _CmndParse_Break_12
  666.         cmp al, byte ptr cs:[ si ]
  667.         jz _CmndParse_Break_16
  668.  
  669.         inc si
  670.         jmp _CmndParse_Break_08
  671.  
  672. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  673. ;  exit
  674. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  675.  
  676. _CmndParse_Break_12:
  677.         or al, al                                       ; non-zero if end of table 
  678.  
  679. _CmndParse_Break_16:
  680.         pop si
  681.         ret
  682.  
  683.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  684.         ;  Scan and Assign Redirection                                  ;
  685.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  686.         ;                                                               ;
  687.         ;  Usage:                                                       ;
  688.         ;   ss:di  argument array                                       ;
  689.         ;   ss:bx  pointer to Execution Control Block                   ;
  690.         ;...............................................................;
  691.  
  692. _assignRedirectedDevices:
  693.  
  694.         Entry
  695.         def __argarray, di                              ; argument array
  696.         def __contargarray, di                          ; continue argument array
  697.         def __execCtrlBlock, bx                         ; execution control block
  698.         defbytes _filenameArg, 128                      ; isolate arg
  699.  
  700.         push di
  701.         pop di
  702.  
  703. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  704. ;  scan remainder of command line for pipe, stdin and stdout args
  705. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  706.  
  707. _assignRedirect_06:
  708.         lea dx, offset [ _filenameArg ][ bp ]           ; address of arg
  709.         getarg di, __contargarray                       ; continue argument array
  710.  
  711. _assignRedirect_08:
  712.         mov si, word ptr [ di ]
  713.         or si, si                                       ; end of args ?
  714.         ifz _assignRedirect_36                          ; yes -->
  715.  
  716.         mov ax, word ptr [ si ]                         ; get arg assignment
  717.         cmp ax, '>>'                                    ; append to stdout ?
  718.         ifz _assignRedirect_AppendStdOut                ; yes -->
  719.         cmp al, '>'                                     ; stdout ?
  720.         jz _assignRedirect_StdOut                       ; yes -->
  721.         cmp al, '<'                                     ; stdin ?
  722.         jz _assignRedirect_StdIn                        ; yes -->
  723.         cmp al, '|'                                     ; pipe ?
  724.         jz _assignRedirect_Pipe                         ; yes -->
  725.  
  726.         inc di
  727.         inc di
  728.         jmp _assignRedirect_08                          ; go to next -->
  729.  
  730. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  731. ;  stdout
  732. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  733.  
  734. _assignRedirect_StdOut:
  735.  
  736.         storarg __contargarray, di                      ; continue argument array
  737.  
  738.         call deleteArg                                  ; kill > arg
  739.         call _asgnGetFileName                           ; arg to _filenameArg [dx]
  740.  
  741.         xor cx, cx
  742.         Int21 CreateFile                                ; if not found, create 
  743.         ifc _assignRedirect_Error                       ; just display error -->
  744.  
  745.         push ax
  746.         mov bx, ax
  747.         mov cx, STDOUT
  748.         call _assignGetCurrHandle
  749.         getarg di, __execCtrlBlock
  750.         mov word ptr [ exCtrlStdOutHandle ][ bx ], ax   ; save old handle
  751.         Int21 ForceFileHandle                           ; redirect stdout
  752.  
  753.         pop bx                                          ; this close frees file handle after 
  754.         Int21 CloseFile                                 ; force replicate handle
  755.         jmp _assignRedirect_06
  756.  
  757. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  758. ;  stdin
  759. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  760.  
  761. _assignRedirect_StdIn:
  762.         storarg __contargarray, di                      ; continue argument array
  763.  
  764.         call deleteArg                                  ; kill < arg
  765.         call _asgnGetFileName                           ; arg to _filenameArg [dx]
  766.  
  767.         lea dx, offset [ _filenameArg ][ bp ]           ; address of arg
  768.         Int21 OpenFile, OPEN_ACCESS_READONLY            ; try to open file
  769.         ifc _assignRedirect_Error                       ; just display error -->
  770.  
  771.         mov bx, ax
  772.         mov cx, STDIN
  773.         call _assignGetCurrHandle
  774.         getarg di, __execCtrlBlock
  775.         mov word ptr [ exCtrlStdInHandle ][ bx ], ax    ; save old handle
  776.         Int21 ForceFileHandle                           ; redirect stdout
  777.  
  778.         jmp _assignRedirect_06
  779.  
  780. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  781. ;  pipe
  782. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  783.  
  784. _assignRedirect_Pipe:
  785.         storarg __contargarray, di                      ; continue argument array
  786.         mov word ptr [ di ], 0000                       ; place an end marker in arg list
  787.  
  788.         mov bx, dx
  789.         mov byte ptr [ bx ], 0
  790.         mov cx, OPEN_ACCESS_READWRITE                   ; create read/write
  791.         Int21 CreateUniqueFile                          ; if not found, create 
  792.         ifc _assignRedirect_Error                       ; just display error -->
  793.  
  794.         push ax
  795.         mov bx, ax
  796.         mov cx, STDOUT
  797.         call _assignGetCurrHandle
  798.  
  799.         getarg di, __execCtrlBlock
  800.         mov word ptr [ exCtrlStdOutHandle ][ di ], ax   ; save old handle
  801.         Int21 ForceFileHandle                           ; redirect stdout
  802.  
  803.         pop bx                                          ; this close frees file handle after 
  804.         Int21 CloseFile                                 ; force replicate handle
  805.  
  806.         getarg di, __contargarray                       ; continue argument array
  807.         getarg bx, __execCtrlBlock                      ; execution control block
  808.         mov word ptr [ exCtrlArgArray. _pointer ][ bx ], di
  809.         or word ptr [ exCtrlFlags ][ bx ], exCtrlPiped  ; say arg is piped.
  810.  
  811.         jmp _assignRedirect_36                          ; exit -->
  812.  
  813. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  814. ;  append stdout
  815. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  816.  
  817. _assignRedirect_AppendStdOut:
  818.  
  819.         storarg __contargarray, di                      ; continue argument array
  820.  
  821.         call deleteArg                                  ; kill > arg
  822.         call deleteArg                                  ; kill > arg
  823.         call _asgnGetFileName                           ; arg to _filenameArg [dx]
  824.         Int21 OpenFile, OPEN_ACCESS_READWRITE           ; try to open file
  825.         jnc _assignRedirect_Append_08
  826.  
  827.         cmp ax, errFileNotFound                         ; if other than not found
  828.         jnz _assignRedirect_Error                       ; just display error -->
  829.  
  830.         xor cx, cx
  831.         lea dx, offset [ _filenameArg ][ bp ]           ; address of arg
  832.         Int21 CreateFile                                ; if not found, create 
  833.         jc _assignRedirect_Error                        ; just display error -->
  834.  
  835. _assignRedirect_Append_08:
  836.         push ax
  837.         xor cx, cx
  838.         xor dx, dx
  839.         mov bx, ax
  840.         Int21 MoveFilePointer, SEEK_END                 ; point to end of file
  841.  
  842.         pop bx
  843.         push bx
  844.         mov cx, 2
  845.         mov dx, offset RxDOS_NewLine
  846.         Int21 WriteFile                                 ; write CRLF
  847.  
  848.         mov cx, STDOUT
  849.         call _assignGetCurrHandle
  850.         getarg bx, __execCtrlBlock
  851.         mov word ptr [ exCtrlStdOutHandle ][ bx ], ax   ; save old handle
  852.  
  853.         pop bx
  854.         push bx
  855.         Int21 ForceFileHandle                           ; redirect stdout
  856.  
  857.         pop bx
  858.         Int21 CloseFile
  859.  
  860.         jmp _assignRedirect_06
  861.  
  862. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  863. ;  redirection error
  864. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  865.  
  866. _assignRedirect_Error:
  867.         call DisplayError
  868.         stc
  869.  
  870. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  871. ;  return
  872. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  873.  
  874. _assignRedirect_36:
  875.         getarg di, __argarray                           ; argument array
  876.         Return
  877.  
  878.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  879.         ;  Kill Arg From List                                           ;
  880.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  881.         ;                                                               ;
  882.         ;  Usage:                                                       ;
  883.         ;   cx     handle whose value we want                           ;
  884.         ;   ax     value of handle returned                             ;
  885.         ;...............................................................;
  886.  
  887. _assignGetCurrHandle:
  888.  
  889.         push es
  890.         push si
  891.         push bx
  892.         push cx
  893.         Int21 GetPSPAddress
  894.  
  895.         pop si                                          ; restore handle offset
  896.         mov es, bx                                      ; set PSP address
  897.         les bx, dword ptr es:[ pspFileHandlePtr ]       ; point to file handles
  898.         mov al, byte ptr es:[ bx + si ]                 ; recover existing handle
  899.         xor ah, ah
  900.  
  901.         pop bx
  902.         pop si
  903.         pop es
  904.         ret
  905.  
  906.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  907.         ;  Copy Arg                                                     ;
  908.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  909.         ;                                                               ;
  910.         ;  Usage:                                                       ;
  911.         ;   si     pointer to argument                                  ;
  912.         ;   di     pointer to copy location                             ;
  913.         ;                                                               ;
  914.         ;  Returns:                                                     ;
  915.         ;   zr     no characters copies                                 ;
  916.         ;...............................................................;
  917.  
  918. _copyArg:
  919.  
  920.         or si, si
  921.         jz _copyArg_36
  922.         or cx, cx                                       ; address of next arg zero ?
  923.         sub cx, si                                      ; real length
  924.  
  925. _copyArg_08:
  926.         lodsb                                           ; get character
  927.         stosb
  928.         or al, al
  929.         jz _copyArg_36
  930.         loop _copyArg_08
  931.  
  932. _copyArg_36:
  933.         ret
  934.  
  935.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  936.         ;  Get Filename From A Piped Or Redirected Argument             ;
  937.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  938.         ;                                                               ;
  939.         ;  Usage:                                                       ;
  940.         ;   di     points to arg list                                   ;
  941.         ;   dx     destination where to copy arg                        ;
  942.         ;                                                               ;
  943.         ;  arg is removed from arg list (it is deleted) once copied     ;
  944.         ;...............................................................;
  945.  
  946. _asgnGetFileName:
  947.  
  948.         push ax
  949.         push dx
  950.         push di
  951.         mov cx, word ptr [ di + 2 ]                     ; get arg that follows
  952.         mov si, word ptr [ di ]                         ; get current arg
  953.         mov di, dx
  954.         call _copyArg
  955.  
  956.         pop di
  957.         call deleteArg                                  ; kill arg
  958.  
  959.         pop dx
  960.         pop ax
  961.         ret
  962.  
  963.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  964.         ;  Close Redirected Std Device                                  ;
  965.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  966.         ;                                                               ;
  967.         ;  Usage:                                                       ;
  968.         ;   al     restore value for handle (or -1)                     ;
  969.         ;   bx     stdout or stdin                                      ;
  970.         ;...............................................................;
  971.  
  972. _CloseRedirectedDevice:
  973.  
  974.         cmp al, -1                                      ; std device redirected ?
  975.         jz _closeRedirect_42                            ; no -->
  976.  
  977.         push es
  978.         push bx
  979.         push ax
  980.         Int21 CloseFile                                 ; close std device
  981.  
  982.         Int21 GetPSPAddress
  983.  
  984.         pop ax
  985.         pop si
  986.         mov es, bx                                      ; set PSP address
  987.         les bx, dword ptr es:[ pspFileHandlePtr ]       ; point to file handles
  988.         xchg al, byte ptr es:[ bx + si ]                ; recover existing handle
  989.  
  990.         pop es
  991.  
  992. _closeRedirect_42:
  993.         ret
  994.  
  995.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  996.         ;  Lookup Argument                                              ;
  997.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  998.         ;                                                               ;
  999.         ;  Usage:                                                       ;
  1000.         ;   ds:si  pointer to argument (term by a null or switch char)  ;
  1001.         ;   cs:di  pointer to supported commands                        ;
  1002.         ;                                                               ;
  1003.         ;  Returns:                                                     ;
  1004.         ;   bx     pointer to command execution address                 ;
  1005.         ;   cy     argument not supported internally                    ;
  1006.         ;...............................................................;
  1007.  
  1008. CmndLookup:
  1009.  
  1010.         push di
  1011.         push si
  1012.  
  1013.         inc di
  1014.         inc di                                          ; point to arg that follows
  1015.  
  1016. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1017. ;  skip leading @ sign
  1018. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1019.  
  1020.         cmp byte ptr [ si ], '@'                        ; command begins with @ sign ?
  1021.         jnz cmndLookup_12                               ; no -->
  1022.         inc si                                          ; skip @ sign 
  1023.  
  1024. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1025. ;  compare argument against table
  1026. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1027.  
  1028. cmndLookup_12:
  1029.         mov al, byte ptr [ si ]                         ; from command
  1030.         inc si
  1031.  
  1032.         cmp al, ' '+1                                   ; if end of command 
  1033.         jc cmndLookup_18                                ; see if all characters match -->
  1034.  
  1035.         cmp al, byte ptr [ _SwitchChar ]                ; switch character ?
  1036.         jz cmndLookup_18                                ; yes, end of arg -->
  1037.         call _CmndParse_Break                           ; parse break ?
  1038.         jz cmndLookup_18                                ; yes, end of arg -->
  1039.  
  1040.         call _lowerCase                                 ; lower case ...
  1041.         cmp al, byte ptr cs:[ di ]                      ; compare
  1042.         jnz cmndLookup_18                               ; if not this command -->
  1043.  
  1044.         inc di                                          ; else keep looking
  1045.         jmp cmndLookup_12
  1046.  
  1047. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1048. ;  if end, see if end of both args
  1049. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1050.  
  1051. cmndLookup_18:
  1052.         cmp byte ptr cs:[ di ], 0                       ; end of command ?
  1053.         jnz cmndLookup_28                               ; not this command then -->
  1054.  
  1055.         dec si
  1056.         mov al, byte ptr [ si ]                         ; get last character
  1057.         cmp al, ' '+1                                   ; end of command ?
  1058.         jc cmndLookup_20                                ; yes -->
  1059.         cmp al, byte ptr [ _SwitchChar ]                ; end of command ?
  1060.         jz cmndLookup_20                                ; yes -->
  1061.         call _CmndParse_Break                           ; parse break ?
  1062.         jz cmndLookup_20                                ; yes -->
  1063.         cmp al, '.'                                     ; end of command ?
  1064.         jz cmndLookup_20                                ; yes -->
  1065.         cmp al, '/'                                     ; end of command ?
  1066.         jz cmndLookup_20                                ; yes -->
  1067.         cmp al, '\'                                     ; end of command ?
  1068.         jnz cmndLookup_28                               ; not this command -->
  1069.  
  1070. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1071. ;  return valid arg
  1072. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1073.  
  1074. cmndLookup_20:
  1075.         pop ax                                          ; leave si pointing at end 
  1076.         pop di
  1077.         mov bx, word ptr cs:[ di ]                      ; where to execute
  1078.         cmp byte ptr [ si ], '\'                        ; command ends with \ ?
  1079.         clc                                             ; NoCarry
  1080.         jmp short cmndLookup_36
  1081.  
  1082. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1083. ;  find next entry in table
  1084. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1085.  
  1086. cmndLookup_28:
  1087.         inc di
  1088.         cmp byte ptr cs:[ di ], 0                       ; end of command ?
  1089.         jnz cmndLookup_28                               ; keep looking -->
  1090.  
  1091.         pop si
  1092.         pop bx                                          ; don't care about saved di
  1093.         inc di                                          ; get next word
  1094.         cmp word ptr cs:[ di ], -1                      ; end of command table ?
  1095.         jnz cmndLookup                                  ; no, lookup next -->
  1096.  
  1097. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1098. ;  return invalid arg
  1099. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1100.  
  1101. cmndLookup_32:
  1102.         stc
  1103.         mov bx, offset _NotValidCommand                 ; default not valid command
  1104.  
  1105. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1106. ;  return
  1107. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1108.  
  1109. cmndLookup_36:
  1110.         ret
  1111.  
  1112.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1113.         ;  Count Number of Arguments                                    ;
  1114.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1115.         ;                                                               ;
  1116.         ;  Usage:                                                       ;
  1117.         ;   ss:di  pointer to argument array                            ;
  1118.         ;                                                               ;
  1119.         ;  Returns:                                                     ;
  1120.         ;   ax     number of arguments in arg array                     ;
  1121.         ;...............................................................;
  1122.  
  1123. CountArgs:
  1124.         push es
  1125.         push di
  1126.         push cx
  1127.  
  1128.         mov cx, 64
  1129.         setES ss
  1130.  
  1131. CountArgs_06:
  1132.         cmp word ptr ss:[ di ], 0000                    ; terminating arg ?
  1133.         jz CountArgs_08                                 ; yes, done -->
  1134.         inc di
  1135.         inc di                                          ; next arg
  1136.         loop CountArgs_06                               ; else, keep looking -->
  1137.  
  1138. CountArgs_08:
  1139.         mov ax, 64
  1140.         sub ax, cx                                      ; # arguments
  1141.  
  1142.         pop cx
  1143.         pop di
  1144.         pop es
  1145.         ret
  1146.  
  1147.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1148.         ;  Pre Process Command Line                                     ;
  1149.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1150.         ;                                                               ;
  1151.         ;  Usage:                                                       ;
  1152.         ;   ss:di  pointer to argument array                            ;
  1153.         ;                                                               ;
  1154.         ;  Returns:                                                     ;
  1155.         ;   cy     too many arguments message output                    ;
  1156.         ;...............................................................;
  1157.  
  1158. CheckNoArgs:
  1159.         xor dx, dx                                      ; no args
  1160.         xor bx, bx                                      ; no switches
  1161.         jmp short PreProcessCmndLine                    ; check
  1162.  
  1163. CheckOneArg:
  1164.         mov cx, 0001                                    ; must have one arg
  1165.         mov dx, 0001                                    ; must have one arg
  1166.         xor bx, bx                                      ; no switches
  1167.         jmp short PreProcessCmndLine                    ; check
  1168.  
  1169. CheckOptOneArg:
  1170.         mov cx, 0000                                    ; must have none, 
  1171.         mov dx, 0001                                    ;   or one arg
  1172.         xor bx, bx                                      ; no switches
  1173.  
  1174.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1175.         ;  Pre Process Command Line                                     ;
  1176.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1177.         ;                                                               ;
  1178.         ;  Usage:                                                       ;
  1179.         ;   ss:di  pointer to argument array                            ;
  1180.         ;   cx     acceptable min # args                                ;
  1181.         ;   dx     acceptable max # args                                ;
  1182.         ;   bx     pointer to switches                                  ;
  1183.         ;                                                               ;
  1184.         ;  Returns:                                                     ;
  1185.         ;   cy     too many arguments message output                    ;
  1186.         ;...............................................................;
  1187.  
  1188. PreProcessCmndLine:
  1189.         push di
  1190.         push cx
  1191.         push dx
  1192.  
  1193.         call _GetSwitches                               ; switches ok ?
  1194.         jc _preProcessCmndLine_08                       ; no -->
  1195.  
  1196.         pop dx
  1197.         pop cx
  1198.         push dx
  1199.         push cx
  1200.         call CountArgs                                  ; see how many args remain
  1201.         call _TooManyArguments                          ; too many still left ?
  1202.         jc _preProcessCmndLine_08                       ; yes -->
  1203.  
  1204.         call nullTerminateArgs                          ; null terminate args
  1205.         or ax, ax                                       ; how many args passed
  1206.  
  1207. _preProcessCmndLine_08:
  1208.         pop dx
  1209.         pop cx
  1210.         pop di
  1211.         ret
  1212.  
  1213.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1214.         ;  Tests for Too Many Arguments                                 ;
  1215.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1216.         ;                                                               ;
  1217.         ;  Usage:                                                       ;
  1218.         ;   ss:di  pointer to argument array                            ;
  1219.         ;   ax     actual argument count                                ;
  1220.         ;   cx     acceptable min # args                                ;
  1221.         ;   dx     acceptable max # args                                ;
  1222.         ;                                                               ;
  1223.         ;  Returns:                                                     ;
  1224.         ;   cy     too many arguments message output                    ;
  1225.         ;...............................................................;
  1226.  
  1227. _TooManyArguments:
  1228.  
  1229.         cmp ax, dx                                      ; 
  1230.         jz _TooManyArguments_08                         ; if expected # args -->
  1231.         jg _TooManyArguments_06                         ; if greater than expected -->
  1232.         cmp ax, cx
  1233.         jge _TooManyArguments_08                        ; if within min/max
  1234.  
  1235. _TooManyArguments_06:
  1236.         push di
  1237.         push ax
  1238.         push cx
  1239.         mov dx, offset CmndError_TooManyParameters
  1240.         Call DisplayLine
  1241.  
  1242.         pop cx
  1243.         push cx
  1244.         add cx, cx
  1245.         add di, cx                                      ; argument ptr that is extra
  1246.         mov dx, word ptr ss:[ di ]                      ; get arg address
  1247.         call DisplayLine                                ; show arg
  1248.  
  1249.         pop cx
  1250.         pop ax
  1251.         pop di
  1252.         stc
  1253.  
  1254. _TooManyArguments_08:
  1255.         ret
  1256.  
  1257.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1258.         ;  Test/ Process Switches                                       ;
  1259.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1260.         ;                                                               ;
  1261.         ;  Usage:                                                       ;
  1262.         ;   ss:di  pointer to argument array                            ;
  1263.         ;   bx     pointer to switches to process (or null)             ;
  1264.         ;                                                               ;
  1265.         ;  Returns:                                                     ;
  1266.         ;   cy     if invalid use of switches                           ;
  1267.         ;                                                               ;
  1268.         ;          Otherwise, switch array passed is filled with info.  ;
  1269.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1270.         ;                                                               ;
  1271.         ;  Switch array consists of a switch letter followed by:        ;
  1272.         ;                                                               ;
  1273.         ;    'x'        switch letter                                   ;
  1274.         ;    flags      type of data value expected                     ;
  1275.         ;    min        min value expected                              ;
  1276.         ;    max        max value expected                              ;
  1277.         ;    actual     actual value passed in command                  ;
  1278.         ;                                                               ;
  1279.         ;    a flag bit is set if the flag was encountered in cmnd.     ;
  1280.         ;...............................................................;
  1281.  
  1282. _GetSwitches:
  1283.         
  1284.         Entry
  1285.         def _switches, bx
  1286.         
  1287.         push di
  1288.         push si
  1289.         push cx
  1290.  
  1291.         or bx, bx                                       ; switches expected ?
  1292.         jz _getSwitches_06                              ; no -->
  1293.         call _initSwitchTable                           ; init switches expected
  1294.         
  1295. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1296. ;  walk through all args
  1297. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1298.  
  1299. _getSwitches_06:
  1300.         mov si, word ptr ss:[ di ]                      ; get arg 
  1301.         or si, si                                       ; is it a null arg ?
  1302.         jz _getSwitches_36                              ; yes, exit -->
  1303.  
  1304.         mov al, byte ptr ss:[ si ]                      ; get value at arg
  1305.         cmp al, byte ptr [ _SwitchChar ]                ; switch arg ?
  1306.         jnz _getSwitches_12                             ; no -->
  1307.  
  1308.         getarg bx, _switches
  1309.         or bx, bx                                       ; any switches allowed ?
  1310.         jz _getSwitches_24                              ; if not allowed, drop from list
  1311.  
  1312.         mov ax, word ptr ss:[ si + 1 ]                  ; get switch characters
  1313.         call _matchSwitch                               ; is this switch valid ?
  1314.         jc _getSwitches_24                              ; not allowed -->
  1315.  
  1316.         or word ptr [ swFlags ][ bx ], SW_SWITCHSET     ; switch is set
  1317.         call deleteArg                                  ; remove this argument
  1318.         jz _getSwitches_36                              ; if no more args -->
  1319.  
  1320. _getSwitches_12:
  1321.         inc di
  1322.         inc di
  1323.         jmp _getSwitches_06
  1324.  
  1325. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1326. ;  switch is illegal
  1327. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1328.  
  1329. _getSwitches_24:
  1330.         push si                                         ; save argument ptr
  1331.         mov dx, offset CmndError_BadSwitch
  1332.         call DisplayLine                                ; error message
  1333.  
  1334.         pop dx
  1335.         call DisplayLine                                ; show arg
  1336.         stc
  1337.  
  1338. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1339. ;  done
  1340. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1341.  
  1342. _getSwitches_36:
  1343.         pop cx
  1344.         pop si
  1345.         pop di
  1346.         Return
  1347.  
  1348.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1349.         ;  Match Switch                                                 ;
  1350.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1351.         ;                                                               ;
  1352.         ;  Usage:                                                       ;
  1353.         ;   al     character                                            ;
  1354.         ;   bx     switch table                                         ;
  1355.         ;                                                               ;
  1356.         ;  Returns:                                                     ;
  1357.         ;   bx     pointer to matchin switch entry                      ;
  1358.         ;   cy     match not found                                      ;
  1359.         ;...............................................................;
  1360.  
  1361. _matchSwitch:
  1362.  
  1363.         call _lowerCase
  1364.  
  1365. _matchSwitch_04:
  1366.         cmp al, byte ptr cs:[ bx ]
  1367.         jz _matchSwitch_08
  1368.  
  1369.         add bx, sizeSWITCHENTRY                         ; next entry
  1370.         cmp byte ptr cs:[ bx ], -1                      ; end of table ?
  1371.         jnz _matchSwitch_04                             ; not yet -->
  1372.  
  1373.         stc
  1374.  
  1375. _matchSwitch_08:
  1376.         ret
  1377.  
  1378.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1379.         ;  Init Switch Table                                            ;
  1380.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1381.         ;                                                               ;
  1382.         ;  Usage:                                                       ;
  1383.         ;   bx     switch table                                         ;
  1384.         ;...............................................................;
  1385.  
  1386. _initSwitchTable:
  1387.  
  1388.         push bx
  1389.  
  1390. _initSwitchTable_04:
  1391.         cmp byte ptr cs:[ bx ], -1                      ; end of table ?
  1392.         jz _initSwitchTable_08                          ; yes, all done -->
  1393.         and word ptr cs:[ swFlags ][ bx ], not SW_SWITCHSET
  1394.         add bx, sizeSWITCHENTRY                         ; next entry
  1395.         jmp _initSwitchTable_04
  1396.  
  1397. _initSwitchTable_08:
  1398.         pop bx
  1399.         ret
  1400.  
  1401.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1402.         ;  Delete Argument                                              ;
  1403.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1404.         ;                                                               ;
  1405.         ;  Usage:                                                       ;
  1406.         ;   ss:di  argument list                                        ;
  1407.         ;...............................................................;
  1408.  
  1409. deleteArg:
  1410.  
  1411.         push di
  1412.         cmp word ptr [ di ], 0000                       ; at end of list ?
  1413.         jz deleteArg_12                                 ; yes -->
  1414.  
  1415. deleteArg_08:
  1416.         mov ax, word ptr [ di+2 ]                       ; get arg
  1417.         mov word ptr [ di ], ax                         ; and move it
  1418.         inc di
  1419.         inc di
  1420.         or ax, ax                                       ; any more ?
  1421.         jnz deleteArg_08                                ; yes -->
  1422.  
  1423.         cmp word ptr [ di+2 ], 0000                     ; two args reqd to actually end copy
  1424.         jnz deleteArg_08                                ; not yet -->
  1425.  
  1426. deleteArg_12:
  1427.         pop di
  1428.         cmp word ptr [ di ], 0000                       ; at end of list ?
  1429.         ret
  1430.  
  1431.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1432.         ;  Null Terminate Args                                          ;
  1433.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1434.         ;                                                               ;
  1435.         ;  Usage:                                                       ;
  1436.         ;   ss:di  argument list                                        ;
  1437.         ;...............................................................;
  1438.  
  1439. nullTerminateArgs:
  1440.  
  1441.         push di
  1442.         push ax
  1443.  
  1444. nullTerminateArgs_04:
  1445.         mov si, word ptr [ di ]
  1446.         or si, si                                       ; more args ?
  1447.         jz nullTerminateArgs_12                         ; no -->
  1448.  
  1449. nullTerminateArgs_06:
  1450.         lodsb                                           ; get character 
  1451.         cmp al, ' '+1                                   ; space or control character ?
  1452.         jc nullTerminateArgs_10                         ; yes -->
  1453.  
  1454.         cmp al, byte ptr [ _SwitchChar ]                ; switch character ?
  1455.         jz nullTerminateArgs_10                         ; yes -->
  1456.         call _CmndParse_Break                           ; parse break ?
  1457.         jnz nullTerminateArgs_06                        ; no, go to next char -->
  1458.  
  1459. nullTerminateArgs_10:
  1460.         mov byte ptr [ si-1 ], 0                        ; place null terminator
  1461.         inc di
  1462.         inc di
  1463.         jmp nullTerminateArgs_04
  1464.  
  1465. nullTerminateArgs_12:
  1466.         pop ax
  1467.         pop di
  1468.         ret
  1469.  
  1470.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1471.         ;  Replace Temporary Variables                                  ;
  1472.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1473.         ;                                                               ;
  1474.         ;  Usage:                                                       ;
  1475.         ;   ss:si  points to null terminated string                     ;
  1476.         ;                                                               ;
  1477.         ;  Returns:                                                     ;
  1478.         ;   cx     length of new string                                 ;
  1479.         ;...............................................................;
  1480.  
  1481. ReplaceTempVariables:
  1482.  
  1483.         Entry
  1484.         def  _stringPointer, si
  1485.         def  _deleteFrom
  1486.         defbytes _tempVar, 128
  1487.  
  1488.         push di
  1489.         push si
  1490.         
  1491. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1492. ;  scan for % argument
  1493. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1494.  
  1495. _replaceTempVar_08:
  1496.         lodsb                                           ; scan for % symbol
  1497.         or al, al                                       ; null terminator ?
  1498.         ifz _replaceTempVar_36                          ; yes -->
  1499.         cmp al, '%'                                     ; percent character ?
  1500.         jnz _replaceTempVar_08
  1501.  
  1502.         mov al, byte ptr [ si ]                         ; get character immed after
  1503.         or al, al                                       ; null terminator ?
  1504.         ifz _replaceTempVar_36                          ; yes -->
  1505.  
  1506.         cmp al, '%'                                     ; %% case ?
  1507.         jz _replaceTempVar_PercentPercent               ; yes -->
  1508.  
  1509.         dec si                                          ; backup over %
  1510.         cmp al, '9'+1                                   ; outside arg values ?
  1511.         jnc _replaceTempVar_EnvVariable                 ; yes -->
  1512.         sub al, '0'                                     ; outside argument values ?
  1513.         jc _replaceTempVar_EnvVariable                  ; yes -->
  1514.  
  1515. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1516. ;  numeric argument
  1517. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1518.  
  1519.         mov cx, 2                                       ; bytes to delete
  1520.         call deleteString                               ; delete cx bytes at si
  1521.  
  1522.         xor ah, ah
  1523.         cmp ax, word ptr [ RxDOS_BatchFile. batchNumArgs ]
  1524.         jge _replaceTempVar_16                          ; just delete arg -->
  1525.  
  1526.         add ax, ax                                      ; index pointer
  1527.         mov di, ax
  1528.         mov di, word ptr [ RxDOS_BatchFile. batchArgPtrs ][ di ]
  1529.         or di, di
  1530.         jz _replaceTempVar_16                           ; if no arg value -->
  1531.         call insertString                               ; insert arg at [ di ]
  1532.  
  1533. _replaceTempVar_16:
  1534.         jmp _replaceTempVar_08
  1535.  
  1536. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1537. ;  %% case
  1538. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1539.  
  1540. _replaceTempVar_PercentPercent:
  1541.         mov cx, 1
  1542.         call deleteString                               ; delete cx bytes at si
  1543.         jmp _replaceTempVar_08
  1544.  
  1545. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1546. ;  environment variable
  1547. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1548.  
  1549. _replaceTempVar_EnvVariable:
  1550.         lea di, offset [ _tempVar ][ bp ]
  1551.         storarg _deleteFrom, si
  1552.         inc si                                          ; skip init %
  1553.  
  1554. _replaceEnvVariable08:
  1555.         lodsb                                           ; scan for next % symbol
  1556.         stosb                                           ; save at _tempvar
  1557.         or al, al                                       ; null terminator ?
  1558.         jz _replaceTempVar_36                           ; yes -->
  1559.         cmp al, '%'                                     ; percent character ?
  1560.         jnz _replaceEnvVariable08                       ; keep searching -->
  1561.  
  1562.         mov word ptr [ di-1 ], '='                      ; cancel trailing %
  1563.  
  1564.         mov cx, si
  1565.         sub cx, word ptr [ _deleteFrom ][ bp ]          ; delete from
  1566.         push si
  1567.         push cx                                         ; delete length
  1568.  
  1569.         lea si, offset [ _tempVar ][ bp ]
  1570.         call searchEnvVariable                          ; environment string found ?
  1571.         jnz _replaceEnvVariable36                       ; not found -->
  1572.  
  1573.         pop cx
  1574.         push cx                                         ; length to delete 
  1575.         mov si, word ptr [ _deleteFrom ][ bp ]          ; delete from
  1576.         call deleteString                               ; delete cx bytes at si
  1577.  
  1578.         push ds
  1579.         mov si, di
  1580.         add si, dx                                      ; contents of variable
  1581.         mov ds, word ptr [ _EnvSegment ]                ; point to segment
  1582.         lea di, offset [ _tempVar ][ bp ]               ; where to copy
  1583.         call _CopyString                                ; copy null term string
  1584.  
  1585.         pop ds
  1586.         mov si, word ptr [ _deleteFrom ][ bp ]          ; delete from
  1587.         lea di, offset [ _tempVar ][ bp ]               ; where to copy
  1588.         call insertString                               ; insert
  1589.  
  1590. _replaceEnvVariable36:
  1591.         pop cx
  1592.         pop si
  1593.         jmp _replaceTempVar_08
  1594.  
  1595. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1596. ;  done
  1597. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1598.  
  1599. _replaceTempVar_36:
  1600.         xor ax, ax
  1601.         mov cx, -1
  1602.         getarg di, _stringPointer
  1603.         repnz scasb
  1604.         neg cx
  1605.         sub cx, 2
  1606.  
  1607.         pop si
  1608.         pop di
  1609.         Return
  1610.  
  1611.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1612.         ;  Replace 'For' Variable                                       ;
  1613.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1614.         ;                                                               ;
  1615.         ;  Usage:                                                       ;
  1616.         ;   ss:si  points to null terminated string                     ;
  1617.         ;   ss:bx  points to null terminated replacement string         ;
  1618.         ;   al     replacement letter                                   ;
  1619.         ;                                                               ;
  1620.         ;  Returns:                                                     ;
  1621.         ;   cx     length of new string                                 ;
  1622.         ;...............................................................;
  1623.  
  1624. ReplaceForVariables:
  1625.  
  1626.         Entry
  1627.         def  _stringPointer, si
  1628.         def  _replaceText, bx
  1629.         def  _replaceVar
  1630.  
  1631.         push di
  1632.         push si
  1633.  
  1634.         call _lowerCase                                 ; replace vars in lower case
  1635.         mov word ptr [ _replaceVar ][ bp ], ax          ; replace variable to ah
  1636.         
  1637. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1638. ;  scan for % argument
  1639. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1640.  
  1641. _replaceForVar_08:
  1642.         lodsb                                           ; scan for % symbol
  1643.         or al, al                                       ; null terminator ?
  1644.         ifz _replaceForVar_36                           ; yes -->
  1645.         cmp al, '%'                                     ; percent character ?
  1646.         jnz _replaceForVar_08
  1647.  
  1648.         mov al, byte ptr [ si ]                         ; get character immed after
  1649.         call _lowerCase
  1650.         cmp al, byte ptr [ _replaceVar ][ bp ]          ; same as var requested ?
  1651.         jnz _replaceForVar_08                           ; not yet -->
  1652.  
  1653. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1654. ;  numeric argument
  1655. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1656.  
  1657.         dec si                                          ; backup over %
  1658.         mov cx, 2                                       ; bytes to delete
  1659.         call deleteString                               ; delete cx bytes at si
  1660.  
  1661.         mov di, word ptr [ _replaceText ][ bp ]         ; insert text
  1662.         call insertString                               ; insert [ di ] arg
  1663.         jmp _replaceForVar_08
  1664.  
  1665. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1666. ;  done
  1667. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1668.  
  1669. _replaceForVar_36:
  1670.         xor ax, ax
  1671.         mov cx, -1
  1672.         getarg di, _stringPointer
  1673.         repnz scasb
  1674.         neg cx
  1675.         sub cx, 2
  1676.  
  1677.         pop si
  1678.         pop di
  1679.         Return
  1680.  
  1681.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1682.         ;  Delete String                                                ;
  1683.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1684.         ;                                                               ;
  1685.         ;  Usage:                                                       ;
  1686.         ;   ss:si  points inside string                                 ;
  1687.         ;   cx     bytes to delete                                      ;
  1688.         ;...............................................................;
  1689.  
  1690. deleteString:
  1691.  
  1692.         push di
  1693.         push ax
  1694.         push si
  1695.         push cx
  1696.         or cx, cx                                       ; if null call
  1697.         jz deleteString_36                              ; nothing to do -->
  1698.  
  1699. deleteString_08:
  1700.         lodsb                                           ; test for null term
  1701.         or al, al
  1702.         jz deleteString_32
  1703.         loop deleteString_08
  1704.  
  1705.         pop cx
  1706.         pop si
  1707.         push si
  1708.         push cx
  1709.         mov di, si
  1710.         add si, cx                                      ; skip pointer
  1711.  
  1712. deleteString_12:
  1713.         lodsb                                           ; copy byte
  1714.         stosb
  1715.         or al, al
  1716.         jnz deleteString_12
  1717.  
  1718.         dec si                                          ; point to null byte
  1719.  
  1720. deleteString_32:
  1721.         mov byte ptr [ si ], 0
  1722.  
  1723. deleteString_36:
  1724.         pop cx
  1725.         pop si
  1726.         pop ax
  1727.         pop di
  1728.         ret        
  1729.  
  1730.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1731.         ;  Insert String                                                ;
  1732.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1733.         ;                                                               ;
  1734.         ;  Usage:                                                       ;
  1735.         ;   ss:si  points inside string                                 ;
  1736.         ;   ds:di  points to insert string (null term)                  ;
  1737.         ;                                                               ;
  1738.         ;  Returns:                                                     ;
  1739.         ;   ss:si  points to char past insert string                    ;
  1740.         ;...............................................................;
  1741.  
  1742. insertString:
  1743.  
  1744.         push cx
  1745.         push ax
  1746.         push di
  1747.  
  1748. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1749. ;  compute length of insert string
  1750. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1751.  
  1752.         xor ax, ax
  1753.         mov cx, -1
  1754.         repnz scasb                                     ; search length of insert string
  1755.  
  1756.         neg cx                                          ; make len-1 positive
  1757.         sub cx, 2                                       ; kill null string arg
  1758.         sub di, 2                                       ; point to last valid byte before null
  1759.         push di                                         ; end of arg pointer
  1760.         push cx                                         ; length of insert string
  1761.  
  1762. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1763. ;  compute length of master string
  1764. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1765.  
  1766.         xor ax, ax
  1767.         mov cx, -1
  1768.         mov di, si
  1769.         repnz scasb                                     ; search length of insert string
  1770.         neg cx                                          ; make len-1 positive
  1771.         dec cx                                          ; kill null string arg
  1772.         dec di
  1773.  
  1774. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1775. ;  open string
  1776. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1777.  
  1778.         std                                             ; copy reverse direction
  1779.         pop ax
  1780.         push ax                                         ; length of insert string
  1781.         mov si, di                                      ; 
  1782.         add di, ax                                      ; where to copy to
  1783.         rep movsb
  1784.  
  1785.         pop cx
  1786.         pop si
  1787.         push di                                         ; save return pointer
  1788.         rep movsb                                       ; insert string
  1789.         cld                                             ; restore direction
  1790.  
  1791. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1792. ;  done
  1793. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1794.  
  1795.         pop si                                          ; return pointer - 1
  1796.         inc si
  1797.  
  1798.         pop di
  1799.         pop ax
  1800.         pop cx
  1801.         ret        
  1802.  
  1803.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1804.         ;  Get Number at String                                         ;
  1805.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1806.         ;                                                               ;
  1807.         ;  Input:                                                       ;
  1808.         ;   ss:si  pointer to text                                      ;
  1809.         ;                                                               ;
  1810.         ;  Returns:                                                     ;
  1811.         ;   ax     contains value                                       ;
  1812.         ;   cy     if value contained text                              ;
  1813.         ;...............................................................;
  1814.  
  1815. _GetNumber:
  1816.         
  1817.         xor dx, dx
  1818.  
  1819. _GetNumber_04:
  1820.         lodsb
  1821.         cmp al, ' '+1                                   ; end of string ?
  1822.         jc _GetNumber_16                                ; yes, exit ok -->
  1823.  
  1824.         cmp al, '9'+1                                   ; valid number ?
  1825.         jnc _GetNumber_14                               ; no, error exit -->
  1826.         sub al, '0'                                     ; valid number ?
  1827.         jc _GetNumber_14                                ; no, error exit -->
  1828.  
  1829.         and ax, 15
  1830.         push ax
  1831.         mov ax, dx
  1832.         add dx, dx                                      ; 2
  1833.         add dx, dx                                      ; 4
  1834.         add dx, ax                                      ; 5
  1835.         add dx, dx                                      ; 10
  1836.         pop ax
  1837.         add dx, ax                                      ; add digit
  1838.         jmp _GetNumber_04                               ; continue -->
  1839.  
  1840. _GetNumber_14:
  1841.         xor ax, ax
  1842.         stc
  1843.         ret
  1844.  
  1845. _GetNumber_16:
  1846.         mov ax, dx
  1847.         or ax, ax
  1848.         ret
  1849.  
  1850.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1851.         ;  Lower Case Character (AL)                                    ;
  1852.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1853.         ;                                                               ;
  1854.         ;  Usage:                                                       ;
  1855.         ;   al     character                                            ;
  1856.         ;...............................................................;
  1857.  
  1858. _lowerCase:
  1859.  
  1860.         cmp al, 'A'
  1861.         jc _lowerCase_10
  1862.         cmp al, 'Z'+1
  1863.         jnc _lowerCase_10
  1864.         or al, 20h                                      ; lower case
  1865.  
  1866. _lowerCase_10:
  1867.         ret
  1868.  
  1869.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1870.         ;  Lower Case String                                            ;
  1871.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1872.         ;                                                               ;
  1873.         ;  Usage:                                                       ;
  1874.         ;   stack  string pointer                                       ;
  1875.         ;                                                               ;
  1876.         ;  Returns:                                                     ;
  1877.         ;   di     points to end (null) byte                            ;
  1878.         ;   cx     characters in string                                 ;
  1879.         ;...............................................................;
  1880.  
  1881. _lowerCaseString:
  1882.         
  1883.         Entry 2
  1884.         darg _string
  1885.  
  1886.         push es
  1887.         xor cx, cx
  1888.         getdarg es, di, _string
  1889.  
  1890. _lowerCaseString_08:
  1891.         mov al, byte ptr es:[ di ]
  1892.         or al, al
  1893.         jz _lowerCaseString_16
  1894.  
  1895.         cmp al, 'A'
  1896.         jc _lowerCaseString_10
  1897.         cmp al, 'Z'+1
  1898.         jnc _lowerCaseString_10
  1899.         or al, 20h                                      ; lower case
  1900.  
  1901. _lowerCaseString_10:
  1902.         mov byte ptr es:[ di ], al
  1903.         inc di
  1904.         inc cx
  1905.         jmp _lowerCaseString_08
  1906.  
  1907. _lowerCaseString_16:
  1908.         pop es
  1909.         Return
  1910.  
  1911.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1912.         ;  Upper Case Character (AL)                                    ;
  1913.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1914.         ;                                                               ;
  1915.         ;  Usage:                                                       ;
  1916.         ;   al     character                                            ;
  1917.         ;...............................................................;
  1918.  
  1919. _upperCase:
  1920.  
  1921.         cmp al, 'a'
  1922.         jc _upperCase_10
  1923.         cmp al, 'z'+1
  1924.         jnc _upperCase_10
  1925.         and al, not 20h                                 ; upper case
  1926.  
  1927. _upperCase_10:
  1928.         ret
  1929.  
  1930.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1931.         ;  Compare Sub Strings                                          ;
  1932.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1933.         ;                                                               ;
  1934.         ;  Usage:                                                       ;
  1935.         ;   si     points to a null terminated string                   ;
  1936.         ;   di     points to longer string                              ;
  1937.         ;                                                               ;
  1938.         ;  Returns:                                                     ;
  1939.         ;   zr     strings match regardless of case                     ;
  1940.         ;...............................................................;
  1941.  
  1942. _compareSubString:
  1943.  
  1944.         mov al, byte ptr [ si ]
  1945.         or al, al
  1946.         jz _compareSubString_08
  1947.  
  1948.         inc si
  1949.         call _lowerCase
  1950.         mov bl, al
  1951.  
  1952.         mov al, byte ptr [ di ]
  1953.         inc di
  1954.         call _lowerCase
  1955.  
  1956.         cmp al, bl
  1957.         jz _compareSubString
  1958.  
  1959. _compareSubString_08:
  1960.         ret
  1961.  
  1962.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1963.         ;  Copy String                                                  ;
  1964.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1965.         ;                                                               ;
  1966.         ;  Usage:                                                       ;
  1967.         ;   si     points to a null terminated string                   ;
  1968.         ;   di     points to destination string                         ;
  1969.         ;...............................................................;
  1970.  
  1971. _copyString:
  1972.         lodsb                                           ; copy character
  1973.         stosb                                           ; copy character
  1974.         or al, al                                       ; until zero byte
  1975.         jnz _copyString
  1976.  
  1977.         ret
  1978.  
  1979.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  1980.         ;  Locate End Of String                                         ;
  1981.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  1982.         ;                                                               ;
  1983.         ;  Usage:                                                       ;
  1984.         ;   di     points to a null terminated string                   ;
  1985.         ;...............................................................;
  1986.  
  1987. _endofString:
  1988.  
  1989.         push ax
  1990.         push cx
  1991.  
  1992.         xor ax, ax
  1993.         mov cx, -1
  1994.         repnz scasb                                     ; locate null terminator
  1995.         dec di                                          ; backup over null byte
  1996.  
  1997.         pop cx
  1998.         pop ax
  1999.         ret
  2000.  
  2001.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2002.         ;  Append Path Name                                             ;
  2003.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2004.         ;                                                               ;
  2005.         ;  Usage:                                                       ;
  2006.         ;   si     points to a null terminated string                   ;
  2007.         ;   di     points to a null terminated string                   ;
  2008.         ;...............................................................;
  2009.  
  2010. _AppendPathName:
  2011.  
  2012.         cmp byte ptr [ di ], 00
  2013.         jz _AppendPathName_12                           ; if no path given, don't search -->
  2014.  
  2015.         xor ax, ax
  2016.         mov cx, -1
  2017.         repnz scasb
  2018.  
  2019.         dec di                                          ; backup to null
  2020.         cmp byte ptr [ di - 1 ], '\'                    ; does path have terminating \ ?
  2021.         jz _AppendPathName_12                           ; yes, no need to add another -->
  2022.  
  2023. _AppendPathName_08:
  2024.         mov byte ptr [ di ], '\'                        ; add terminating \
  2025.         inc di
  2026.  
  2027. _AppendPathName_12:
  2028.         call _CopyString
  2029.         ret
  2030.  
  2031.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2032.         ;  Search Env String                                            ;
  2033.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2034.         ;                                                               ;
  2035.         ;  Input:                                                       ;
  2036.         ;   ds:si  points to input command string                       ;
  2037.         ;                                                               ;
  2038.         ;  Output:                                                      ;
  2039.         ;   ds:si  points to end of input string (imm after =)          ;
  2040.         ;   es:di  points to name value in env string                   ;
  2041.         ;      dx  offset in env variable to value past = sign          ;
  2042.         ;   nz     env variable not found                               ;
  2043.         ;...............................................................;
  2044.  
  2045. searchEnvVariable:
  2046.  
  2047.         Entry
  2048.         def _search, si                                 ; search text
  2049.         def _envbegpointer, 0000                        ; located env variable
  2050.  
  2051.         push es
  2052.         mov es, word ptr [ _EnvSegment ]                ; point to segment
  2053.         xor di, di
  2054.  
  2055. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2056. ;  search through each item
  2057. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2058.  
  2059. searchEnvVariable_08:
  2060.         storarg _envbegpointer, di                      ; located env variable
  2061.         getarg si, _search                              ; get search text pointer
  2062.         cmp byte ptr es:[ di ], 00                      ; end of env area ?
  2063.         jz searchEnvNotFound                            ; not found -->
  2064.         
  2065. searchEnvVariable_12:
  2066.         mov al, byte ptr [ si ]
  2067.         or al, al                                       ; if end string -->
  2068.         jz searchEnvVariable_Next                       ; not equal, skip to next -->
  2069.  
  2070.         call _upperCase                                 ; conv to upper case
  2071.         mov ah, al
  2072.  
  2073.         mov al, byte ptr es:[ di ]                      ; compare
  2074.         call _upperCase                                 ; conv to upper case
  2075.  
  2076.         cmp ah, al                                      ; compare
  2077.         jnz searchEnvVariable_Next                      ; not equal, skip to next -->
  2078.  
  2079.         inc si
  2080.         inc di
  2081.         cmp al, '='                                     ; at equal sign ?
  2082.         jz searchEnvVariableFound                       ; we have search item -->
  2083.         cmp byte ptr es:[ di-1 ], 00                    ; end of env string ?
  2084.         jnz searchEnvVariable_12                        ; continue -->
  2085.         jmp searchEnvVariable_08
  2086.  
  2087. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2088. ;  skip to next env variable
  2089. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2090.  
  2091. searchEnvVariable_Next:
  2092.         inc di
  2093.         cmp byte ptr es:[ di-1 ], 00                    ; end of env string ?
  2094.         jnz searchEnvVariable_Next                      ; continue -->
  2095.         jmp searchEnvVariable_08
  2096.  
  2097. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2098. ;  item not found
  2099. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2100.  
  2101. searchEnvNotFound:
  2102.         mov ax, es
  2103.         or ax, ax                                       ; not zero means not found
  2104.         jmp short searchEnvReturn
  2105.  
  2106. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2107. ;  item found
  2108. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2109.  
  2110. searchEnvVariableFound:
  2111.         mov dx, word ptr [ _envbegpointer ][ bp ]       ; return start pointer
  2112.         sub di, dx                                      ; distance from beg pointer
  2113.         xchg di, dx                                     ; return offset in dx
  2114.         xor ax, ax
  2115.  
  2116. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2117. ;  return
  2118. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2119.  
  2120. searchEnvReturn:
  2121.         pop es
  2122.         Return
  2123.  
  2124.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2125.         ;  Delete Env Variable                                          ;
  2126.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2127.         ;                                                               ;
  2128.         ;  Usage:                                                       ;
  2129.         ;   di     pointer to env entry to delete                       ;
  2130.         ;                                                               ;
  2131.         ;  Returns:                                                     ;
  2132.         ;   di     pointer to end byte of environment                   ;
  2133.         ;   ax     bytes available in Environment                       ;
  2134.         ;...............................................................;
  2135.  
  2136. deleteEnvVariable:
  2137.  
  2138.         push es
  2139.         mov es, word ptr [ _EnvSegment ]                ; point to segment
  2140.         cmp byte ptr es:[ di ], 00                      ; at end of env block ?
  2141.         jz deleteEnvVariable_36                         ; yes, don't delete -->
  2142.  
  2143. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2144. ;  locate start of next string
  2145. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2146.  
  2147.         mov si, di                                      ; save di pointer
  2148.  
  2149. deleteEnvVariable_08:
  2150.         inc si
  2151.         cmp byte ptr es:[ si-1 ], 00                    ; locate end of this string 
  2152.         jnz deleteEnvVariable_08                        ; continue -->
  2153.  
  2154. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2155. ;  is this end of env block ?
  2156. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2157.  
  2158. deleteEnvVariable_12:
  2159.         mov byte ptr es:[ di ], 00                      ; put end mark.
  2160.         cmp byte ptr es:[ si ], 00                      ; at end of env block ?
  2161.         jz deleteEnvVariable_36                         ; yes, end of delete -->
  2162.  
  2163. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2164. ;  copy a string
  2165. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2166.  
  2167. deleteEnvVariable_16:
  2168.         mov al, byte ptr es:[ si ]
  2169.         stosb                                           ; copy byte
  2170.         inc si
  2171.         or al, al                                       ; did we copy a null terminator ?
  2172.         jnz deleteEnvVariable_16                        ; not yet -->
  2173.         jmp deleteEnvVariable_12                        ; 
  2174.  
  2175. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2176. ;  return
  2177. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2178.  
  2179. deleteEnvVariable_36:
  2180.         mov ax, word ptr [ _EnvSize ]
  2181.         sub ax, di                                      ; space left
  2182.  
  2183.         pop es
  2184.         ret
  2185.  
  2186.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2187.         ;  Insert Env Variable                                          ;
  2188.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2189.         ;                                                               ;
  2190.         ;  Usage:                                                       ;
  2191.         ;   si     pointer to text to insert into environment           ;
  2192.         ;   di     must point to end null byte of environment block     ;
  2193.         ;                                                               ;
  2194.         ;  Returns:                                                     ;
  2195.         ;   ax     bytes remaining in Environment                       ;
  2196.         ;   cy     if could not add to environment block                ;
  2197.         ;...............................................................;
  2198.  
  2199. insertEnvVariable:
  2200.  
  2201.         Entry
  2202.         def endPointer, di
  2203.  
  2204.         push es
  2205.         mov es, word ptr [ _EnvSegment ]                ; point to segment
  2206.  
  2207.         mov cx, word ptr [ _EnvSize ]
  2208.         sub cx, di                                      ; bytes available
  2209.         jle insertEnvVariable_36                        ; if none -->
  2210.  
  2211. insertEnvVariable_08:
  2212.         lodsb
  2213.         stosb                                           ; copy byte
  2214.         or al, al                                       ; all done ?
  2215.         jz insertEnvVariable_36                         ; yes -->
  2216.  
  2217.         loop insertEnvVariable_08
  2218.  
  2219. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2220. ;  can't insert (insufficient space)
  2221. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2222.  
  2223.         stc                                             ; error, if not all copied
  2224.         mov ax, 0000
  2225.         getarg di, endPointer                           ; restore pointer to old end
  2226.         mov byte ptr es:[ di ], 00                      ; restore end pointer
  2227.  
  2228.         pop es
  2229.         Return
  2230.  
  2231. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2232. ;  return
  2233. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2234.  
  2235. insertEnvVariable_36:
  2236.         mov ax, word ptr [ _EnvSize ]
  2237.         sub ax, di                                      ; space left
  2238.         mov byte ptr es:[ di ], 00                      ; put end pointer
  2239.  
  2240.         pop es
  2241.         Return
  2242.  
  2243.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2244.         ;  Find Program or Bat File                                     ;
  2245.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2246.         ;                                                               ;
  2247.         ;  Usage:                                                       ;
  2248.         ;   ss:si  pointer to name (not null terminated)                ;
  2249.         ;                                                               ;
  2250.         ;  Returns:                                                     ;
  2251.         ;   cy     not found anywhere in path                           ;
  2252.         ;   ax     contains type of program found                       ;
  2253.         ;           0000 - program is a batch file                      ;
  2254.         ;           0001 - program is a com or exe file                 ;
  2255.         ;   bx     contains handle to file                              ;
  2256.         ;...............................................................;
  2257.  
  2258. _findProgram:
  2259.  
  2260.         Entry
  2261.         def _pathArg, dx                                ; where to store path
  2262.         def _pathpointer                                ; PATH=, if any
  2263.         def _endofname
  2264.         def _endofpathname
  2265.         def _dontSearch, false
  2266.         defbytes _execname, 128
  2267.  
  2268. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2269. ;  isolate name from rest of command line
  2270. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2271.  
  2272.         lea di, offset [ _execname ][ bp ]              ; pointer to copy field
  2273.  
  2274. _findProgram_08:
  2275.         lodsb                                           ; get character 
  2276.         stosb                                           ; copy it
  2277.         cmp al, ' '+1                                   ; space or control character ?
  2278.         jc _findProgram_20                              ; yes -->
  2279.         cmp al, '|'                                     ; pipe character ?
  2280.         jz _findProgram_20                              ; yes -->
  2281.         cmp al, '*'                                     ; wild character ?
  2282.         ifz _findProgram_Error                          ; yes -->
  2283.         cmp al, '?'                                     ; wild character ?
  2284.         ifz _findProgram_Error                          ; yes -->
  2285.  
  2286.         cmp al, byte ptr [ _SwitchChar ]                ; switch character ?
  2287.         jz _findProgram_20                              ; yes -->
  2288.  
  2289.         cmp al, '\'                                     ; file name contains path info ?
  2290.         jz _findProgram_12                              ; don't search path= -->
  2291.         cmp al, '/'                                     ; file name contains path info ?
  2292.         jnz _findProgram_14                             ; don't search path= -->
  2293.  
  2294. _findProgram_12:
  2295.         mov byte ptr [ _dontSearch ][ bp ], true
  2296.  
  2297. _findProgram_14:
  2298.         call _CmndParse_Break                           ; parse break ?
  2299.         jnz _findProgram_08                             ; yes -->
  2300.  
  2301. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2302. ;  search through current directory first
  2303. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2304.  
  2305. _findProgram_20:
  2306.         dec di
  2307.         mov byte ptr [ di ], 0                          ; place null terminator
  2308.  
  2309.         lea si, offset [ _execname ][ bp ]              ; pointer to copy field
  2310.         mov di, word ptr [ _pathArg ][ bp ]             ; pointer to path arg
  2311.         mov word ptr [ _endofpathname ][ bp ], di       ; save end of path name pointer
  2312.         call _CopyString                                ; append filename
  2313.  
  2314.         mov dx, word ptr [ _pathArg ][ bp ]             ; pointer to path arg
  2315.         Int21 FindFirstFile                             ; locate file
  2316.         jnc _findProgram_50                             ; if located -->
  2317.  
  2318.         mov si, offset RxDOS_PathSpec
  2319.         call searchEnvVariable                          ; locate PATH=
  2320.         add di, dx                                      ; address after =
  2321.         storarg _pathpointer, di                        ; location of path statement
  2322.  
  2323. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2324. ;  search through search order
  2325. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2326.  
  2327. _findProgram_30:
  2328.         lea si, offset [ _execname ][ bp ]              ; pointer to copy field
  2329.         getarg di, _endofpathname                       ; where to copy name
  2330.         call _CopyString                                ; append filename
  2331.  
  2332.         dec di
  2333.         mov word ptr [ _endofname ][ bp ], di           ; save end name pointer
  2334.  
  2335.         mov si, offset RxDOS_ExecOrder                  ; look for names in order, current dir
  2336.  
  2337. _findProgram_32:
  2338.         getarg di, _endofname
  2339.         call _CopyString                                ; copy extension
  2340.  
  2341.         push si                                         ; save pointer
  2342.         mov dx, word ptr [ _pathArg ][ bp ]             ; pointer to path arg
  2343.         Int21 FindFirstFile                             ; locate file
  2344.         pop si                                          ; restore si
  2345.         jnc _findProgram_50                             ; if located -->
  2346.  
  2347.         cmp byte ptr [ si ], -1                         ; end of search order list ?
  2348.         jnz _findProgram_32                             ; not yet -->
  2349.  
  2350. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2351. ;  locate next search path
  2352. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2353.  
  2354.         cmp byte ptr [ _dontSearch ][ bp ], true        ; search path ?
  2355.         jz _findProgram_CantFind                        ; no, can't find -->
  2356.  
  2357.         push ds
  2358.         mov ds, word ptr [ _EnvSegment ]
  2359.         mov si, word ptr [ _pathpointer ][ bp ]         ; path=
  2360.         mov di, word ptr [ _pathArg ][ bp ]             ; pointer to path arg
  2361.  
  2362. _findProgram_36:
  2363.         lodsb
  2364.         or al, al
  2365.         jz _findProgram_38
  2366.         cmp al, ';'
  2367.         jz _findProgram_40
  2368.  
  2369.         stosb
  2370.         jmp _findProgram_36
  2371.  
  2372. _findProgram_38:
  2373.         mov byte ptr [ _dontSearch ][ bp ], true        ; don't search any longer (end of path)
  2374.  
  2375. _findProgram_40:
  2376.         storarg _pathpointer, si                        ; save end of path search
  2377.         pop ds                                          ; restore ds
  2378.  
  2379.         mov al, '\'
  2380.         cmp al, byte ptr [ di - 1 ]                     ; pathname terminated by \ ?
  2381.         jz _findProgram_42                              ; yes -->
  2382.         stosb                                           ; add \ to pathname
  2383.  
  2384. _findProgram_42:
  2385.         storarg _endofpathname, di                      ; save path name
  2386.         jmp _findProgram_30
  2387.  
  2388. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2389. ;  file found, determine if .exe or .com
  2390. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2391.  
  2392. _findProgram_50:
  2393.         mov si, offset [ RxDOS_DTA. findFileName ]
  2394.         
  2395. _findProgram_52:
  2396.         lodsb                                           ; get filename character
  2397.         or al, al                                       ; end of name ?
  2398.         jz _findProgram_56                              ; yes, assume .bat -->
  2399.         cmp al, '.'                                     ; extension located ?
  2400.         jnz _findProgram_52                             ; no, keep scanning -->
  2401.  
  2402.         lodsw                                           ; get filename character
  2403.         mov cx, ax
  2404.         or cx, '  '                                     ; force lower case 
  2405.  
  2406.         lodsb
  2407.         xor ah, ah
  2408.         or al, ' '                                      ; lower case
  2409.         add cx, ax                                      ; checksum
  2410.  
  2411.         mov ax, _EXE                                    ; _exe
  2412.         cmp cx, ( 'xe' + 'e' )                          ; exe ?
  2413.         jz _findProgram_62                              ; probably -->
  2414.  
  2415.         mov ax, _COM                                    ; _com
  2416.         cmp cx, ( 'oc' + 'm' )                          ; com ?
  2417.         jz _findProgram_62                              ; probably -->
  2418.  
  2419. _findProgram_56:
  2420.         mov ax, _BAT                                    ; _com
  2421.  
  2422. _findProgram_62:
  2423.         or ax, ax                                       ; no carry
  2424.         Return
  2425.  
  2426. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2427. ;  error
  2428. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2429.  
  2430. _findProgram_CantFind:
  2431. _findProgram_Error:
  2432.         stc
  2433.         Return
  2434.  
  2435.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2436.         ;  return volume name                                           ;
  2437.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2438.         ;                                                               ;
  2439.         ;  Usage:                                                       ;
  2440.         ;   al     is disk to read volume                               ;
  2441.         ;   di     pointer to volume name (in DTA)                      ;
  2442.         ;   cy     drive has no volume name                             ;
  2443.         ;...............................................................;
  2444.  
  2445. returnVolumeName:
  2446.  
  2447.         cmp al, 'Z'-40h
  2448.         jnc returnVolumeName_08
  2449.  
  2450.         or al, al                                       ; default disk ?
  2451.         jnz returnVolumeName_06                         ; no -->
  2452.  
  2453.         Int21 CurrentDisk
  2454.         inc al                                          ; a=1, ...
  2455.  
  2456. returnVolumeName_06:
  2457.         add al, 'a'-1
  2458.  
  2459. returnVolumeName_08:
  2460.         mov di, offset RxDOS_RootDirectory - 2
  2461.         mov byte ptr [ di ], al
  2462.  
  2463.         mov dx, di
  2464.         mov cx, ATTR_VOLUME
  2465.         mov di, offset [ RxDOS_DTA. findFileName ]
  2466.         mov byte ptr [ di ], 0
  2467.         Int21 FindFirstFile                             ; find volume name
  2468.  
  2469.         mov dx, 0                                       ; assume no error
  2470.         jnc returnVolumeName_18                         ; return zero (found )
  2471.  
  2472.         mov dx, 1                                       ; else assume not found error
  2473.         cmp al, errPathNotFound                         ; if path not found,
  2474.         jnz returnVolumeName_18                         ; then return NZ -->
  2475.         stc
  2476.         ret
  2477.  
  2478. returnVolumeName_18:
  2479.         or dx, dx
  2480.         ret
  2481.  
  2482.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2483.         ;  Get Error Code                                               ;
  2484.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2485.         ;                                                               ;
  2486.         ;  Usage:                                                       ;
  2487.         ;   ax     error code                                           ;
  2488.         ;...............................................................;
  2489.  
  2490. DisplayError:
  2491.  
  2492.         push bx
  2493.         cmp ax, CmndError_RefTableEntries
  2494.         jnc DisplayError_08
  2495.  
  2496.         mov bx, ax
  2497.         add bx, bx
  2498.         add bx, offset CmndError_TextReferenceTable
  2499.         mov dx, word ptr cs:[ bx ]                      ; get address of message
  2500.         cmp dx, 0000                                    ; error not defined ?
  2501.         jz DisplayError_08
  2502.         call DisplayErrorMessage                        ; display message
  2503.  
  2504. DisplayError_08:
  2505.         pop bx
  2506.         ret
  2507.  
  2508.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2509.         ;  Display Error Message                                        ;
  2510.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2511.         ;                                                               ;
  2512.         ;  Usage:                                                       ;
  2513.         ;   cs:dx  points to error message                              ;
  2514.         ;...............................................................;
  2515.  
  2516. DisplayErrorMessage:
  2517.  
  2518.         call DisplayLine                                ; print line
  2519.         call CRLF                                       ; new line
  2520.         stc
  2521.         ret
  2522.  
  2523.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2524.         ;  Display Cr/Lf                                                ;
  2525.         ;...............................................................;
  2526.  
  2527. CRLF:
  2528.         push es
  2529.         push dx
  2530.  
  2531.         setES ds
  2532.         mov dx, offset RxDOS_NewLine
  2533.         call DisplayLine                                ; cr/lf
  2534.         pop dx
  2535.         pop es
  2536.         ret
  2537.  
  2538.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2539.         ;  Display Line                                                 ;
  2540.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2541.         ;                                                               ;
  2542.         ;  Usage:                                                       ;
  2543.         ;   es:si  points to message                                    ;
  2544.         ;...............................................................;
  2545.  
  2546. DisplayLine:
  2547.  
  2548.         push si
  2549.         mov si, dx
  2550.  
  2551. DisplayLine_08:
  2552.         mov dl, byte ptr es:[ si ]
  2553.         or dl, dl                                       ; end of string ?
  2554.         jz DisplayLine_16                               ; yes -->
  2555.         inc si
  2556.         Int21 DisplayOutput
  2557.  
  2558.         cmp dl, 'J'-40h                                 ; new line ?
  2559.         jnz DisplayLine_08                              ; no -->
  2560.  
  2561.         call _Paginate                                  ; account for line
  2562.         call _CheckControlC                             ; see if control C
  2563.         jnc DisplayLine_08                              ; continue -->
  2564.  
  2565. DisplayLine_16:
  2566.         pop si
  2567.         clc
  2568.         ret
  2569.  
  2570.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2571.         ;  Display Line Count                                           ;
  2572.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2573.         ;                                                               ;
  2574.         ;  Usage:                                                       ;
  2575.         ;   es:dx  points to message                                    ;
  2576.         ;   cx     characters                                           ;
  2577.         ;...............................................................;
  2578.  
  2579. DisplayLineCount:
  2580.  
  2581.         Entry
  2582.         def _count, cx
  2583.  
  2584.         push si
  2585.         mov si, dx
  2586.  
  2587. DisplayLineCount_08:
  2588.         mov dl, byte ptr es:[ si ]
  2589.         inc si
  2590.         Int21 DisplayOutput
  2591.  
  2592.         cmp dl, 'J'-40h                                 ; new line ?
  2593.         jnz DisplayLineCount_12                         ; no -->
  2594.         call _Paginate                                  ; account for line
  2595.         call _CheckControlC                             ; see if control C
  2596.         jc DisplayLineCount_16                          ; if abort -->
  2597.  
  2598. DisplayLineCount_12:
  2599.         dec word ptr [ _count ][ bp ]
  2600.         jnz DisplayLineCount_08
  2601.  
  2602. DisplayLineCount_16:
  2603.         pop si
  2604.         Return                
  2605.  
  2606.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2607.         ;  Paginate                                                     ;
  2608.         ;...............................................................;
  2609.  
  2610. _Paginate:
  2611.         push si
  2612.         call isStdOutAFile
  2613.         jz _Paginate_14                                 ; yes, no pause needed -->
  2614.  
  2615.         cmp byte ptr [ PageLines ], 00                  ; page lines ?
  2616.         jz _Paginate_14                                 ; don't worry about lines
  2617.  
  2618.         inc word ptr [ LinesDisplayed ]                 ; incr lines displayed
  2619.  
  2620.         call GetScreenLines
  2621.         dec ax                                          ; # lines on screen -1
  2622.         cmp ax, word ptr [ LinesDisplayed ]             ; beyond # screen lines ?
  2623.         jg _Paginate_14                                 ; not yet -->
  2624.  
  2625.         mov word ptr [ LinesDisplayed ], 0000           ; reset screen lines
  2626.         call _Pause
  2627.  
  2628. _Paginate_14:
  2629.         pop si
  2630.         ret 
  2631.  
  2632.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2633.         ;  Set Paging Mode                                              ;
  2634.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2635.         ;                                                               ;
  2636.         ;  If value is 8000 (switch is set), then set Paging Mode.      ;
  2637.         ;                                                               ;
  2638.         ;...............................................................;
  2639.  
  2640. setPagingMode:
  2641.  
  2642.         mov byte ptr [ PageLines ], 00                  ; paging mode
  2643.         and ax, SW_SWITCHSET
  2644.         jz setPagingMode_08
  2645.  
  2646.         mov byte ptr [ PageLines ], -1                  ; paging mode
  2647.         mov word ptr [ LinesDisplayed ], 0000           ; # lines displayed, curr page
  2648.  
  2649. setPagingMode_08:
  2650.         ret
  2651.  
  2652.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2653.         ;  Is StdOut A File ?                                           ;
  2654.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2655.         ;                                                               ;
  2656.         ;  Returns:                                                     ;
  2657.         ;   zr     stdout is a file                                     ;
  2658.         ;   nz     stdout is NOT a file                                 ;
  2659.         ;...............................................................;
  2660.  
  2661. isStdOutAFile:
  2662.         
  2663.         mov bx, STDOUT
  2664.         Int21 IoControl, 00h                            ; is device piped from a file ?
  2665.         mov ax, 1                                       ; non-zero value
  2666.         jc _isStdOutAFile_No                            ; we'll assume its not -->
  2667.  
  2668.         test dx, 80h                                    ; if bit 7 = 0, handle is a file
  2669.         jnz _isStdOutAFile_No                           ; we'll assume its not -->
  2670.         
  2671. _isStdOutAFile_Yes:
  2672.         xor ax, ax                                      ; zero value if bat file
  2673.  
  2674. _isStdOutAFile_No:
  2675.         or ax, ax
  2676.         ret
  2677.  
  2678.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2679.         ;  Check Control C                                              ;
  2680.         ;...............................................................;
  2681.  
  2682. _CheckControlC:
  2683.  
  2684.         clc
  2685.         ret
  2686.  
  2687.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2688.         ;  Scan Print Buffer                                            ;
  2689.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2690.         ;                                                               ;
  2691.         ;  This routine accepts a variable number of arguments and for- ;
  2692.         ;  mats an output buffer.  It works very similar to C's sprintf ;
  2693.         ;  function.                                                    ;
  2694.         ;                                                               ;
  2695.         ;  The input buffer may contain imbedded formatting codes:      ;
  2696.         ;                                                               ;
  2697.         ;  %c      insert character (pointer to character on stack)     ;
  2698.         ;  %s      insert string    (pointer to string on stack)        ;
  2699.         ;  %d      insert decimal   (pointer to decimal on stack)       ;
  2700.         ;  %ld     insert long      (pointer to long on stack)          ;
  2701.         ;                                                               ;
  2702.         ;  If a format command contains numbers, the number is inter-   ;
  2703.         ;  preted as a field width.  The output value will be right     ;
  2704.         ;  aligned within the field width if the width is preceeded     ;
  2705.         ;  with a negative sign.  Any characters that exceeds the field ;
  2706.         ;  width is ignored.                                            ;
  2707.         ;                                                               ;
  2708.         ;  If a format command contains a comma, the number will be     ;
  2709.         ;  decimal edited.                                              ;
  2710.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2711.         ;                                                               ;
  2712.         ;  Usage:                                                       ;
  2713.         ;   stack  argument                                             ;
  2714.         ;     .    argument                                             ;
  2715.         ;     .    argument                                             ;
  2716.         ;   stack  argument                                             ;
  2717.         ;   stack  format buffer                                        ;
  2718.         ;   stack  output buffer                                        ;
  2719.         ;                                                               ;
  2720.         ;  Returns:                                                     ;
  2721.         ;   dx     pointer to output buffer                             ;
  2722.         ;...............................................................;
  2723.  
  2724. _sprintf:
  2725.  
  2726.         Entry 2
  2727.         arg _format
  2728.         arg _output
  2729.         def _args, 0000
  2730.         def _varg
  2731.         def _fieldwidth
  2732.         def _fieldflags
  2733.  
  2734. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2735. ;  scan/copy buffer
  2736. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2737.  
  2738.         lea di, word ptr [ _format ][ bp ]
  2739.         add di, 2                                       ; point to prev arg
  2740.         storarg _varg, di                               ; save var arg pointer
  2741.  
  2742.         mov si, word ptr [ _format ][ bp ]
  2743.         mov di, word ptr [ _output ][ bp ]
  2744.  
  2745. _sprintf_06:
  2746.         mov word ptr [ _fieldwidth ][ bp ], 0000        ; no width
  2747.         mov word ptr [ _fieldflags ][ bp ], 0000        ; no flags
  2748.  
  2749. _sprintf_08:
  2750.         lodsb                                           ; get character
  2751.         stosb                                           ; copy to output
  2752.         or al, al                                       ; all done ?
  2753.         ifz _sprintf_86                                 ; yes -->
  2754.  
  2755.         cmp al, '%'                                     ; format code ?
  2756.         jnz _sprintf_08                                 ; not yet -->
  2757.         
  2758. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2759. ;  format code
  2760. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2761.  
  2762.         mov word ptr [ _fieldwidth ][ bp ], 0000        ; no width
  2763.         mov word ptr [ _fieldflags ][ bp ], 0000        ; no flags
  2764.  
  2765.         dec di                                          ; kill format % in output
  2766.         mov byte ptr [ di ], 0                          ; stick a null code there
  2767.  
  2768. _sprintf_12:
  2769.         lodsb                                           ; get character that follows
  2770.         call _lowerCase                                 ; make it lower case
  2771.  
  2772.         or al, al                                       ; all done ?
  2773.         ifz _sprintf_86                                 ; yes -->
  2774.  
  2775. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2776. ;  is it long ?
  2777. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2778.  
  2779.         cmp al, 'l'                                     ; long flag ?
  2780.         jnz _sprintf_14                                 ; no -->
  2781.         or word ptr [ _fieldflags ][ bp ], SPRINTF_LONGFLAG
  2782.         jmp _sprintf_12
  2783.  
  2784. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2785. ;  is it a left justify
  2786. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2787.  
  2788. _sprintf_14:
  2789.         cmp al, '-'                                     ; left justify
  2790.         jnz _sprintf_16                                 ; no -->
  2791.         or word ptr [ _fieldflags ][ bp ], SPRINTF_LEFTALIGN
  2792.         jmp _sprintf_12
  2793.  
  2794. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2795. ;  is it a comma (decimal) delimeter ?
  2796. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2797.  
  2798. _sprintf_16:
  2799.         cmp al, ','                                     ; decimal delimeter ?
  2800.         jnz _sprintf_18                                 ; no -->
  2801.         or word ptr [ _fieldflags ][ bp ], SPRINTF_COMMADELIM
  2802.         jmp _sprintf_12
  2803.  
  2804. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2805. ;  is it a field width ?
  2806. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2807.  
  2808. _sprintf_18:
  2809.         cmp al, '9'+1                                   ; number ?
  2810.         jnc _sprintf_22                                 ; no -->
  2811.         cmp al, '0'                                     ; number ?
  2812.         jc _sprintf_22                                  ; no -->
  2813.  
  2814.         and ax, 15                                      ; get number
  2815.         mov dx, word ptr [ _fieldwidth ][ bp ]          ; get width
  2816.         add dx, dx                                      ; x2
  2817.         add dx, dx                                      ; x4
  2818.         add dx, word ptr [ _fieldwidth ][ bp ]          ; x5
  2819.         add dx, dx                                      ; x10
  2820.         add dx, ax
  2821.         mov word ptr [ _fieldwidth ][ bp ], dx
  2822.         jmp _sprintf_12
  2823.  
  2824. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2825. ;  see if its a valid formatting code
  2826. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2827.  
  2828. _sprintf_22:
  2829.         cmp al, 'd'                                     ; decimal output ?
  2830.         jz _sprintf_26
  2831.         cmp al, 'x'                                     ; hex output ?
  2832.         jz _sprintf_26
  2833.         cmp al, 'c'                                     ; character ?
  2834.         jz _sprintf_32
  2835.         cmp al, 's'                                     ; string ?
  2836.         jz _sprintf_36
  2837.         cmp al, '%'                                     ; percent percent ?
  2838.         jz _sprintf_46
  2839.  
  2840.         jmp _sprintf_06
  2841.  
  2842. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2843. ;  decimal
  2844. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2845.  
  2846. _sprintf_26:
  2847.         push si
  2848.         getarg si, _varg                                ; get variable arg ptr
  2849.         mov si, word ptr [ si ]                         ; get argument pointer        
  2850.         add word ptr [ _varg ][ bp ], 2
  2851.         inc word ptr [ _args ][ bp ]
  2852.  
  2853.      ;** doesn't support right justified
  2854.  
  2855.         xor dx, dx
  2856.         mov ax, word ptr [ si ]                         ; get number
  2857.         test word ptr [ _fieldflags ][ bp ], SPRINTF_LONGFLAG
  2858.         jz _sprintf_28
  2859.         mov dx, word ptr [ si+2 ]                       ; get long
  2860.  
  2861. _sprintf_28:
  2862.         mov bx, word ptr [ _fieldflags ][ bp ]          ; flags
  2863.         mov cx, word ptr [ _fieldwidth ][ bp ]          ; width
  2864.         call _sprintfNum                                ; convert numeric to ascii
  2865.  
  2866.         pop si
  2867.         jmp _sprintf_06
  2868.  
  2869. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2870. ;  character
  2871. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2872.  
  2873. _sprintf_32:
  2874.         push si
  2875.         getarg si, _varg                                ; get variable arg ptr
  2876.         mov si, word ptr [ si ]                         ; get argument pointer        
  2877.         add word ptr [ _varg ][ bp ], 2
  2878.         inc word ptr [ _args ][ bp ]
  2879.  
  2880.      ;** doesn't support right justified
  2881.         mov cx, word ptr [ _fieldwidth ][ bp ]          ; width
  2882.         call _sprintfInitField
  2883.  
  2884.         mov al, byte ptr [ si ]
  2885.         stosb                                           ; store character
  2886.  
  2887.         pop si
  2888.  
  2889.         mov cx, word ptr [ _fieldwidth ][ bp ]          ; width
  2890.         or cx, cx
  2891.         ifz _sprintf_06
  2892.  
  2893.         dec cx
  2894.         call _sprintfPadField
  2895.         jmp _sprintf_06
  2896.  
  2897. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2898. ;  string
  2899. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2900.  
  2901. _sprintf_36:
  2902.         push si
  2903.         getarg si, _varg                                ; get variable arg ptr
  2904.         mov si, word ptr [ si ]                         ; get argument pointer        
  2905.         add word ptr [ _varg ][ bp ], 2
  2906.         inc word ptr [ _args ][ bp ]
  2907.  
  2908.      ;** doesn't support right justified
  2909.  
  2910.         mov cx, word ptr [ _fieldwidth ][ bp ]          ; width
  2911.         call _sprintfInitField
  2912.  
  2913. _sprintf_38:
  2914.         lodsb
  2915.         or al, al                                       ; null terminator ?
  2916.         jz _sprintf_40                                  ; yes -->
  2917.         stosb
  2918.         or cx, cx                                       ; fixed count ?
  2919.         jz _sprintf_38
  2920.         loop _sprintf_38
  2921.  
  2922. _sprintf_40:
  2923.         or cx, cx                                       ; still more length to go ?
  2924.         jz _sprintf_42                                  ; no -->
  2925.         add di, cx                                      ; advance field length
  2926.  
  2927. _sprintf_42:
  2928.         pop si
  2929.         jmp _sprintf_06
  2930.  
  2931. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2932. ;  %
  2933. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2934.  
  2935. _sprintf_46:
  2936.         stosb
  2937.         jmp _sprintf_06
  2938.  
  2939. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2940. ;  all done
  2941. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  2942.  
  2943. _sprintf_86:
  2944.         mov ax, word ptr [ _args   ][ bp ]
  2945.         add ax, ax                                      ; # words left on stack
  2946.         mov si, word ptr [ _output ][ bp ]
  2947.         mov dx, si
  2948.         Return
  2949.  
  2950.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  2951.         ;  Convert Long (dx:ax) to Ascii                                ;
  2952.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  2953.         ;                                                               ;
  2954.         ;  Usage:                                                       ;
  2955.         ;   dx:ax  long value                                           ;
  2956.         ;   cx     size of field to right justify                       ;
  2957.         ;   bx     display option flags:                                ;
  2958.         ;          8000  insert decimal commas                          ;
  2959.         ;                                                               ;
  2960.         ;...............................................................;
  2961.  
  2962. _sprintfNum:
  2963.  
  2964.         Entry
  2965.         defbytes _decDisplay, 16
  2966.         def _decimalflag, bx
  2967.         def _fieldwidth, cx
  2968.         def _spacing
  2969.  
  2970.         push si
  2971.         push di
  2972.         call _sprintfInitField                          ; init field to spaces
  2973.         mov byte ptr [ _spacing ][ bp ], 03             ; set spacing
  2974.  
  2975.         lea di, offset [ _decDisplay ][ bp ]
  2976.         push di
  2977.  
  2978. _sprintfNum_08:
  2979.         mov cx, 10
  2980.         call _div32                                     ; divide by 10
  2981.         or cl, '0'
  2982.         mov byte ptr [ di ], cl                         ; store character
  2983.         inc di
  2984.         
  2985.         mov cx, dx
  2986.         or cx, ax                                       ; more to go ?
  2987.         jz _sprintfNum_10                               ; no -->
  2988.  
  2989.         test word ptr [ _decimalflag ][ bp ], SPRINTF_COMMADELIM
  2990.         jz _sprintfNum_10                               ; no -->
  2991.         dec byte ptr [ _spacing ][ bp ]                 ; spacing break ?
  2992.         jnz _sprintfNum_10                              ; not yet -->
  2993.  
  2994.         mov byte ptr [ _spacing ][ bp ], 03             ; set spacing
  2995.         mov byte ptr [ di ], ','                        ; store comma
  2996.         inc di
  2997.  
  2998. _sprintfNum_10:
  2999.         mov cx, dx
  3000.         or cx, ax                                       ; more to go ?
  3001.         jnz _sprintfNum_08                              ; yes -->
  3002.         
  3003.         pop cx
  3004.         sub di, cx                                      ; total # chars output
  3005.         mov cx, di                                      ; length to cx
  3006.  
  3007.         pop di
  3008.         push di                                         ; where to begin right justify
  3009.         lea si, offset [ _decDisplay ][ bp ]            ; where data stored
  3010.         cmp word ptr [ _fieldwidth ][ bp ], 0000        ; left justified output ?
  3011.         jz _sprintfNum_20                               ; yes -->
  3012.  
  3013. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3014. ;  right justified
  3015. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3016.  
  3017.     ; be sure to blank fill field first
  3018.  
  3019.         add di, word ptr [ _fieldwidth ][ bp ]          ; 
  3020.         push di
  3021.  
  3022. _sprintfNum_16:
  3023.         lodsb                                           ; get character
  3024.         dec di
  3025.         mov byte ptr [ di ], al                         
  3026.         loop _sprintfNum_16
  3027.  
  3028.         pop di
  3029.         jmp short _sprintfNum_32
  3030.  
  3031. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3032. ;  left justified
  3033. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3034.  
  3035. _sprintfNum_20:
  3036.         lodsb                                           ; get character
  3037.         stosb
  3038.         loop _sprintfNum_20
  3039.  
  3040. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3041. ;  done
  3042. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3043.  
  3044. _sprintfNum_32:
  3045.         pop si                                          ; drop saved di
  3046.         pop si
  3047.         Return
  3048.  
  3049.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3050.         ;  Init Field to Spaces                                         ;
  3051.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3052.         ;                                                               ;
  3053.         ;  Usage:                                                       ;
  3054.         ;   di     pointer to buffer                                    ;
  3055.         ;   cx     width of field                                       ;
  3056.         ;   bx     8000 if right justified                              ;
  3057.         ;...............................................................;
  3058.  
  3059. _sprintfInitField:
  3060.         
  3061.         or cx, cx                                       ; fixed count ?
  3062.         jz _sprintfInitField_08                         ; no -->
  3063.  
  3064.         push di
  3065.         push cx
  3066.         push ax
  3067.         mov al, ' '
  3068.         rep stosb
  3069.  
  3070.         pop ax
  3071.         pop cx
  3072.         pop di
  3073.  
  3074. _sprintfInitField_08:
  3075.         ret
  3076.  
  3077.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3078.         ;  Pad Field                                                    ;
  3079.         ;...............................................................;
  3080.  
  3081. _sprintfPadField:
  3082.         or cx, cx                                       ; still more length to go ?
  3083.         jz _sprintfPadField_08                          ; no -->
  3084.         add di, cx                                      ; advance field length
  3085.  
  3086. _sprintfPadField_08:
  3087.         ret
  3088.  
  3089.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3090.         ;  32 Bit Divide                                                ;
  3091.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3092.         ;                                                               ;
  3093.         ;  Input:                                                       ;
  3094.         ;   ax:dx  numerator                                            ;
  3095.         ;   cx     divisor                                              ;
  3096.         ;                                                               ;
  3097.         ;...............................................................;
  3098.  
  3099. _div32: or cx, cx                                       ; protect from zero divisor
  3100.         stc                                             ; in case of error
  3101.         jz _div32_return                                ; if so, just return with carry
  3102.  
  3103.         push bx
  3104.         mov bx, dx
  3105.         xchg ax, bx
  3106.         xor dx, dx
  3107.         div cx
  3108.       
  3109.         xchg ax, bx
  3110.         div cx                                          ; remainder will be in dx
  3111.         mov cx, dx
  3112.         mov dx, bx
  3113.         pop bx
  3114.  
  3115. _div32_return:
  3116.         ret
  3117.  
  3118.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3119.         ;  Get Screen Lines                                             ;
  3120.         ;...............................................................;
  3121.  
  3122. GetScreenLines:
  3123.         
  3124.         push ds
  3125.         push bx
  3126.         xor bx, bx
  3127.         mov ds, bx
  3128.         mov bx, offset 484h
  3129.         mov al, byte ptr [ bx ]                         ; Video Rows
  3130.         cbw                                             ; extend to full word
  3131.         inc al                                          ; correct number
  3132.         pop bx
  3133.         pop ds
  3134.         ret
  3135.  
  3136.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3137.         ;  Physical Screen Clear                                        ;
  3138.         ;...............................................................;
  3139.  
  3140. PhysClearScreen:
  3141.  
  3142.         call GetScreenLines
  3143.         mov dh, al
  3144.         mov dl, 80
  3145.  
  3146.         mov ax, 0600h                                   ; entire screen
  3147.         mov bx, 7100h                                   ; blue/white        
  3148.         mov cx, 0000h                                   ; from home row
  3149.         int 10h
  3150.  
  3151.         mov ax, 0200h
  3152.         mov bx, 0000h
  3153.         mov dx, 0000h
  3154.         int 10h                                         ; position cursor
  3155.  
  3156.         ret
  3157.  
  3158.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3159.         ;  Commands (Alphabetical)                                      ;
  3160.         ;...............................................................;
  3161.  
  3162.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3163.         ;  Break [ ON | OFF ]                                           ;
  3164.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3165.         ;                                                               ;
  3166.         ;  Sets, clears or reports on RxDOS break option.               ;
  3167.         ;                                                               ;
  3168.         ;...............................................................;
  3169.  
  3170. _Break:
  3171.  
  3172.         Entry
  3173.         ddef __argarray, ss, di
  3174.         def _args, ax
  3175.  
  3176.         call CheckOptOneArg                             ; see if 1 arg 
  3177.         jc _BreakExit                                   ; if error -->
  3178.         
  3179.         or ax, ax                                       ; any arguments ?
  3180.         jz _BreakPrintcurrent                           ; none, print current status -->
  3181.  
  3182. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3183. ;  test for On/ Off
  3184. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3185.  
  3186.         mov si, word ptr [ di ]                         ; get single argument
  3187.         mov di, offset RxDOS_OnOff
  3188.         call CmndLookup                                 ; lookup command
  3189.         jc _BreakError                                  ; if not on/off, print line -->
  3190.  
  3191.         mov dl, bl
  3192.         Int21 CtrlBreakCheck, setControlC               ; set/clear Ctrl Break check
  3193.         Return
  3194.  
  3195. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3196. ;  must specify on or off
  3197. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3198.  
  3199. _BreakError:
  3200.         mov dx, offset CmndError_MustSpecifyOnOff
  3201.         call DisplayErrorMessage
  3202.         Return
  3203.  
  3204. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3205. ;  print verify on/off value
  3206. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3207.  
  3208. _BreakPrintcurrent:
  3209.         Int21 CtrlBreakCheck, getControlC               ; get/clear Ctrl Break check
  3210.  
  3211.         mov bl, dl
  3212.         xor bh, bh
  3213.         add bx, bx
  3214.         mov dx, word ptr [ _BreakOptions ][ bx ]
  3215.         call DisplayLine
  3216.  
  3217. _BreakExit:
  3218.         Return
  3219.  
  3220.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3221.         ;  Change Directory                                             ;
  3222.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3223.         ;                                                               ;
  3224.         ;  Unlike most other commands, cd command will be processed if  ;
  3225.         ;  part of the cd command, as in cd\...                         ;
  3226.         ;                                                               ;
  3227.         ;  Usage:                                                       ;
  3228.         ;   ss:di  Arg Array                                            ;
  3229.         ;   ax     Number of arguments in array                         ;
  3230.         ;...............................................................;
  3231.  
  3232. _Call:
  3233.  
  3234.         Entry
  3235.         def __argarray, di
  3236.         def __progname, si
  3237.         def __tempargptr
  3238.         defbytes _pathArg, 128
  3239.  
  3240. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3241. ;  find program
  3242. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3243.  
  3244.         lea dx, offset [ _pathArg ][ bp ]               ; where to return fully qualified path name
  3245.         call _findProgram                               ; locate program or bat file
  3246.         jc _call_12                                     ; if program not found -->
  3247.         cmp ax, _BAT                                    ; is it a bat program ?
  3248.         jz _call_22                                     ; yes -->
  3249.  
  3250.         mov di, word ptr [ __argarray ][ bp ]
  3251.       ; call _loadProgram                               ; else load and execute program
  3252.         Return                                          ; return
  3253.  
  3254. _call_12:
  3255.         call _NotValidCommand                           ; not valid (not found )
  3256.         Return                                          ; return
  3257.  
  3258. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3259. ;  execute (call) batch
  3260. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3261.  
  3262. _call_22:
  3263.         lea dx, offset [ _pathArg ][ bp ]               ; pointer to file name
  3264.         Int21 OpenFile, 00h                             ; read only
  3265.         push ax                                         ; save batch file handle
  3266.  
  3267.         xor cx, cx
  3268.         xor dx, dx
  3269.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  3270.         Int21 MoveFilePointer, SEEK_CUR                 ; get current position
  3271.  
  3272.         mov word ptr [ RxDOS_BatchFile. batchFilePosition. _low ], ax
  3273.         mov word ptr [ RxDOS_BatchFile. batchFilePosition. _high ], dx
  3274.  
  3275.         mov si, offset RxDOS_BatchFile
  3276.         mov di, word ptr [ RxDOS_PrevStackFrame ]
  3277.         mov cx, sizeBATCH_ARGS
  3278.         rep movsb                                       ; copy current args to save area
  3279.  
  3280.         sub word ptr [ RxDOS_PrevStackFrame ], sizeBATCH_ARGS
  3281.         inc word ptr [ RxDOS_StackFrameNumEntries ]
  3282.  
  3283. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3284. ;  setup batch file arguments
  3285. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3286.  
  3287.         pop word ptr [ RxDOS_BatchFile. batchFileHandle ]
  3288.  
  3289.         mov di, word ptr [ __argarray ][ bp ]           ; arguments pointer
  3290.         call nullTerminateArgs
  3291.  
  3292.         mov di, offset ( RxDOS_BatchFile. batchArgStore )
  3293.         mov word ptr [ RxDOS_BatchFile. batchNumArgs ], 0
  3294.         mov si, word ptr [ __argarray ][ bp ]           ; arguments pointer
  3295.         storarg __tempargptr, si
  3296.  
  3297. _call_32:
  3298.         getarg si, __tempargptr
  3299.         mov si, word ptr [ si ]                         ; arg
  3300.         or si, si                                       ; null terminator ?
  3301.         jz _call_36                                     ; then all done -->
  3302.  
  3303.         add word ptr [ __tempargptr ][ bp ], 2
  3304.         mov bx, word ptr [ RxDOS_BatchFile. batchNumArgs ]
  3305.         add bx, bx
  3306.         mov word ptr [ RxDOS_BatchFile. batchArgPtrs ][ bx ], di
  3307.         mov word ptr [ RxDOS_BatchFile. batchArgPtrs + 2 ][ bx ], 0000
  3308.         inc word ptr [ RxDOS_BatchFile. batchNumArgs ]
  3309.  
  3310.         call _CopyString
  3311.         jmp _call_32
  3312.  
  3313. _call_36:
  3314.         Return
  3315.  
  3316.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3317.         ;  Change Directory                                             ;
  3318.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3319.         ;                                                               ;
  3320.         ;  Unlike most other commands, cd command will be processed if  ;
  3321.         ;  part of the cd command, as in cd\...                         ;
  3322.         ;                                                               ;
  3323.         ;  Usage:                                                       ;
  3324.         ;   ss:di  Arg Array                                            ;
  3325.         ;   ax     Number of arguments in array                         ;
  3326.         ;...............................................................;
  3327.  
  3328. _ChangeDir:
  3329.         
  3330.         Entry
  3331.         def  _disk
  3332.         ddef __argarray, ss, di
  3333.         defbytes _tempstring, 128
  3334.  
  3335.         call CheckOptOneArg                             ; see if 1 arg 
  3336.         ifc _changeDir_32                               ; if switch not expected -->
  3337.         jnz _changeDir_18                               ; if argument passed -->
  3338.  
  3339. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3340. ;  display current
  3341. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3342.  
  3343.         Int21 CurrentDisk                               ; get current disk
  3344.  
  3345.         mov dl, al                                      ; save drive letter
  3346.         or al, 'a'                                      ; drive
  3347.         lea di, offset [ _tempstring + 3][ bp ]
  3348.         mov byte ptr [ di - 3 ], al
  3349.         mov byte ptr [ di - 2 ], ':'
  3350.         mov byte ptr [ di - 1 ], '\'
  3351.  
  3352.         inc dl
  3353.         mov si, di
  3354.         Int21 GetCurrentDirectory                       ; get current directory
  3355.  
  3356.         push ss
  3357.         push si                                         ; where string
  3358.         call _lowerCaseString
  3359.  
  3360.         lea dx, offset _tempstring [ bp ]
  3361.         call DisplayLine
  3362.         Return
  3363.  
  3364. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3365. ;  change drive: directory
  3366. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3367.  
  3368. _changeDir_18:
  3369.         mov di, word ptr [ __argarray. _pointer ][ bp ]
  3370.         mov si, word ptr ss:[ di ]                      ; pointer to lead argument
  3371.         lea di, offset [ _tempstring ][ bp ]
  3372.         mov word ptr [ di ], '\'                        ; init area
  3373.         Int21 GetActualFileName                         ; expand name
  3374.  
  3375.         mov di, word ptr [ __argarray. _pointer ][ bp ]
  3376.         mov si, word ptr ss:[ di ]                      ; pointer to lead argument
  3377.         cmp byte ptr [ si+1 ], ':'                      ; drive ?
  3378.         jnz _changeDir_22                               ; no -->
  3379.         
  3380.         mov al, byte ptr [ si ]                         ; get drive letter
  3381.         call _lowerCase                                 ; lower case letter
  3382.         mov dl, al                                      ; to dl
  3383.         sub dl, 'a'                                     ; drive maps to 0, ...
  3384.         mov byte ptr [ _disk ][ bp ], dl                ; save disk
  3385.  
  3386.         Int21 SelectDisk                                ; can we select a drive ?
  3387.         Int21 CurrentDisk                               ; get current disk
  3388.  
  3389.         inc si
  3390.         inc si                                          ; point [si] past drive
  3391.         cmp al, byte ptr [ _disk ][ bp ]                ; disk changed ?
  3392.         jz _changeDir_22                                ; yes -->
  3393.  
  3394.         mov dx, offset CmndError_InvalidDrive
  3395.         call DisplayErrorMessage                        ; display message
  3396.         jmp short _changeDir_32
  3397.  
  3398. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3399. ;  change directory
  3400. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3401.  
  3402. _changeDir_22:
  3403.         mov dx, si                                      ; points to change string
  3404.         Int21 ChangeSubdirectory                        ; try changing dir
  3405.         jnc _changeDir_32                               ; if invalid
  3406.         call DisplayError                               ; if error
  3407.  
  3408. _changeDir_32:
  3409.         Return
  3410.  
  3411.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3412.         ;  Clear Screen                                                 ;
  3413.         ;...............................................................;
  3414.  
  3415. _Cls:
  3416.         call CheckNoArgs                                ; check for no args
  3417.         jc _cls_36                                      ; if error -->
  3418.  
  3419. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3420. ;  stdout a device or file
  3421. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3422.  
  3423.         mov bx, STDOUT
  3424.         Int21 IoControl, 00h                            ; is device piped to a file ?
  3425.         jc _clsScreen                                   ; we'll assume its to screen -->
  3426.  
  3427.         test dx, 80h                                    ; if bit 7 = 0, handle is a file
  3428.         jnz _clsScreen                                  ; its a physical device -->
  3429.  
  3430.         mov dl, 'L'-40h                                 ; to a file we'll pipe a top of forms
  3431.         Int21 DisplayOutput
  3432.         jmp short _cls_36
  3433.  
  3434. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3435. ;  see how many lines
  3436. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3437.  
  3438. _clsScreen:
  3439.         call PhysClearScreen
  3440.  
  3441. _cls_36:
  3442.         ret
  3443.  
  3444.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3445.         ;  Delete filename                                              ;
  3446.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3447.         ;                                                               ;
  3448.         ;  Usage:                                                       ;
  3449.         ;   ss:di  Arg Array                                            ;
  3450.         ;   ax     Number of arguments in array                         ;
  3451.         ;...............................................................;
  3452.  
  3453. _Delete:
  3454.  
  3455.         Entry
  3456.         def __argarray, di
  3457.         def _nfiles, 0000
  3458.         def _filename
  3459.         defbytes _expandedname, 128
  3460.  
  3461.         call CheckOneArg
  3462.         jnc _Delete_06                                  ; arguments wrong -->
  3463.  
  3464.         mov dx, offset CmndError_FileNameMissing
  3465.         call DisplayErrorMessage
  3466.         Return
  3467.  
  3468. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3469. ;  try to locate file (s)
  3470. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3471.  
  3472. _Delete_06:
  3473.         mov dx, word ptr [ di ]                         ; point to filename arg
  3474.         storarg _filename, dx                           ; save pointer
  3475.  
  3476. _Delete_08:
  3477.         xor cx, cx
  3478.         getarg dx, _filename                            ; get filename pointer
  3479.         Int21 FindFirstFile                             ; does file exist ?
  3480.         jc _Delete_36                                   ; no more -->
  3481.  
  3482.         mov si, offset [ RxDOS_DTA. findFileName ]      ; current name
  3483.         lea di, offset [ _expandedname ][ bp ]
  3484.         Int21 GetActualFileName                         ; expand name
  3485.         jc _Delete_36                                   ; can't resolve name -->
  3486.  
  3487.         inc word ptr [ _nfiles ][ bp ]
  3488.         lea dx, offset [ _expandedname ][ bp ]
  3489.         Int21 DeleteFile                                ; delete file
  3490.         jmp _Delete_08
  3491.  
  3492. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3493. ;  try to locate file 
  3494. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3495.  
  3496. _Delete_36:
  3497.         cmp word ptr [ _nfiles ][ bp ], 0000            ; any files deleted ?
  3498.         jnz _Delete_42                                  ; yes -->
  3499.  
  3500.         mov dx, offset CmndError_NoFilesFound
  3501.         call DisplayErrorMessage
  3502.  
  3503. _Delete_42:
  3504.         Return
  3505.  
  3506.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3507.         ;  Disk Select Command                                          ;
  3508.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3509.         ;                                                               ;
  3510.         ;  Usage:                                                       ;
  3511.         ;   ss:di  Arg Array                                            ;
  3512.         ;   ax     Number of arguments in array                         ;
  3513.         ;...............................................................;
  3514.  
  3515. _DiskSelect:
  3516.         push di
  3517.         inc di
  3518.         inc di
  3519.         call CheckNoArgs                                ; check for no arguments 
  3520.         jc _diskSelect_32                               ; if error -->
  3521.  
  3522.         pop di
  3523.         push di                                         ; restore pointer to arg 0
  3524.         mov si, word ptr ss:[ di ]                      ; pointer to lead argument
  3525.         cmp byte ptr [ si+1 ], ':'                      ; drive ?
  3526.         jnz _diskSelect_32                              ; no -->
  3527.         
  3528.         mov al, byte ptr [ si ]                         ; get drive letter
  3529.         call _lowerCase                                 ; lower case letter
  3530.         mov dl, al                                      ; to dl
  3531.         sub dl, 'a'                                     ; drive maps to 0, ...
  3532.         mov byte ptr [ _disk ][ bp ], dl                ; save disk
  3533.  
  3534.         Int21 SelectDisk                                ; can we select a drive ?
  3535.         Int21 CurrentDisk                               ; get current disk
  3536.  
  3537.         inc si
  3538.         inc si                                          ; point [si] past drive
  3539.         cmp al, byte ptr [ _disk ][ bp ]                ; disk changed ?
  3540.         jz _diskSelect_32                               ; yes -->
  3541.  
  3542.         mov dx, offset CmndError_InvalidDrive
  3543.         call DisplayErrorMessage                        ; display message
  3544.  
  3545. _diskSelect_32:
  3546.         pop di
  3547.         ret
  3548.  
  3549.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3550.         ;  Echo                                                         ;
  3551.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3552.         ;                                                               ;
  3553.         ;  Usage:                                                       ;
  3554.         ;   ss:di  Arg Array                                            ;
  3555.         ;   ax     Number of arguments in array                         ;
  3556.         ;...............................................................;
  3557.  
  3558. _Echo:
  3559.  
  3560.         Entry
  3561.         ddef __argarray, ss, di
  3562.         def _args, ax
  3563.  
  3564.         or ax, ax                                       ; no arguments ?
  3565.         jz _echo_printcurrent                           ; none, print current status -->
  3566.  
  3567.         dec ax                                          ; just one argument ?
  3568.         jnz _echo_printline                             ; no, print line -->
  3569.  
  3570. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3571. ;  test for On/ Off
  3572. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3573.  
  3574.         mov si, word ptr [ di ]                         ; get single argument
  3575.         mov di, offset RxDOS_OnOff
  3576.         call CmndLookup                                 ; lookup command
  3577.         jc _echo_printline                              ; if not on/off, print line -->
  3578.  
  3579.         mov byte ptr [ _EchoStatus ], bl                ; set echo status 
  3580.         Return
  3581.  
  3582. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3583. ;  print current line
  3584. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3585.  
  3586. _echo_printline:
  3587.         mov di, word ptr [ __argarray. _pointer ][ bp ]
  3588.         mov dx, word ptr [ di ]                         ; get start of string
  3589.         call DisplayLine
  3590.         call CRLF
  3591.         Return
  3592.  
  3593. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3594. ;  print on/off value
  3595. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3596.  
  3597. _echo_printcurrent:
  3598.         mov bl, byte ptr [ _EchoStatus ]
  3599.         xor bh, bh
  3600.         add bx, bx
  3601.         mov dx, word ptr [ _EchoOptions ][ bx ]
  3602.         call DisplayLine
  3603.         Return
  3604.  
  3605.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3606.         ;  End Call                                                     ;
  3607.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3608.         ;                                                               ;
  3609.         ;  Usage:                                                       ;
  3610.         ;   ss:di  Arg Array                                            ;
  3611.         ;   ax     Number of arguments in array                         ;
  3612.         ;...............................................................;
  3613.  
  3614. _EndCall:
  3615.  
  3616.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  3617.         Int21 CloseFile                                 ; close file
  3618.         mov word ptr [ RxDOS_BatchFile. batchFileHandle ], 0000
  3619.  
  3620.         cmp word ptr [ RxDOS_StackFrameNumEntries ], 0000
  3621.         jz _endcall_18                                  ; if no more files to backup to -->
  3622.  
  3623.         dec word ptr [ RxDOS_StackFrameNumEntries ]
  3624.         add word ptr [ RxDOS_PrevStackFrame ], sizeBATCH_ARGS
  3625.         mov si, word ptr [ RxDOS_PrevStackFrame ]
  3626.         mov di, offset RxDOS_BatchFile
  3627.         mov cx, sizeBATCH_ARGS
  3628.         rep movsb                                       ; copy current args to save area
  3629.  
  3630.         mov si, word ptr [ RxDOS_PrevStackFrame ]
  3631.  
  3632.         cmp word ptr [ RxDOS_StackFrameNumEntries ], 0000
  3633.         jnz _endcall_18                                 ; if more files to backup to -->
  3634.         mov byte ptr [ _EchoStatus ], Yes
  3635.  
  3636. _endcall_18:
  3637.         ret
  3638.  
  3639.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3640.         ;  Execute Program or Batch File                                ;
  3641.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3642.         ;                                                               ;
  3643.         ;  Usage:                                                       ;
  3644.         ;   ss:di  Arg Array                                            ;
  3645.         ;   ax     Number of arguments in array                         ;
  3646.         ;...............................................................;
  3647.  
  3648. _executeProgram:
  3649.  
  3650.      ; eventually, check for .exe and .com, of course
  3651.  
  3652.         call _Call
  3653.         ret
  3654.  
  3655.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3656.         ;  Goto Label                                                   ;
  3657.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3658.         ;                                                               ;
  3659.         ;  if batch file, locate label                                  ;
  3660.         ;...............................................................;
  3661.  
  3662. _Goto:
  3663.  
  3664.         Entry
  3665.         def  _labelPtr, si
  3666.         ddef _filePosition
  3667.         defbytes _buffer, sizeCmdLineStruct
  3668.  
  3669. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3670. ;  prep argument
  3671. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3672.  
  3673. _goto_06:
  3674.         cmp byte ptr [ si ], ':'
  3675.         jnz _goto_08
  3676.         inc si
  3677.         jmp _goto_06
  3678.  
  3679. _goto_08:
  3680.         storarg _labelPtr, si
  3681.  
  3682. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3683. ;  running batch file ?
  3684. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3685.  
  3686.         cmp word ptr [ RxDOS_BatchFile. batchFileHandle ], 0000
  3687.         jz _Goto_36                                     ; if not running a batch file -->
  3688.  
  3689.         call CheckOneArg                                ; must have an arg
  3690.         jc _Goto_36                                     ; error -->
  3691.  
  3692.         call getBatchPosition                           ; save current batch file position
  3693.         mov word ptr [ _filePosition. _low  ][ bp ], ax
  3694.         mov word ptr [ _filePosition. _high ][ bp ], dx
  3695.  
  3696. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3697. ;  read lines 
  3698. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3699.  
  3700.         xor cx, cx
  3701.         xor dx, dx
  3702.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  3703.         Int21 MoveFilePointer, SEEK_BEG                 ; start at beg of file        
  3704.  
  3705. _goto_16:
  3706.         xor ax, ax                                      ; no echo searching lines
  3707.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  3708.         lea si, offset [ _buffer ][ bp ]
  3709.         mov byte ptr [ bufMaxLength ][ si ], sizeCmdLine
  3710.         call _ReadBatch                                 ; read batch line
  3711.         jz _goto_32                                     ; set position -->
  3712.  
  3713. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3714. ;  compare against search argument
  3715. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3716.  
  3717.         xor bh, bh
  3718.         mov bl, byte ptr [ _buffer. bufActualLength ][ bp ]
  3719.         lea di, offset [ _buffer. bufData ][ bp ]
  3720.         mov byte ptr [ di + bx ], 00
  3721.         mov si, word ptr [ _labelPtr ][ bp ]
  3722.  
  3723. _goto_18:
  3724.         cmp byte ptr [ di ], ' '
  3725.         jz _goto_22
  3726.         cmp byte ptr [ di ], ':'
  3727.         jnz _goto_26
  3728.  
  3729. _goto_22:
  3730.         inc di
  3731.         jmp _goto_18
  3732.  
  3733. _goto_26:
  3734.         call _compareSubString                          ; label located ?
  3735.         jnz _goto_16                                    ; no -->
  3736.         jmp short _goto_36                              ; line located !
  3737.  
  3738. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3739. ;  can't find, reset line location
  3740. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3741.  
  3742. _goto_32:
  3743.         mov dx, word ptr [ _filePosition. _low  ][ bp ]
  3744.         mov cx, word ptr [ _filePosition. _high ][ bp ]
  3745.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  3746.         Int21 MoveFilePointer, SEEK_BEG                 ; restore pointer
  3747.  
  3748. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3749. ;  return
  3750. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3751.  
  3752. _goto_36:
  3753.         Return
  3754.  
  3755.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3756.         ;  If [not] ERRORLEVEL number command                           ;
  3757.         ;  If [not] EXIST filename command                              ;
  3758.         ;  If [not] string1==string2 command                            ;
  3759.         ;...............................................................;
  3760.  
  3761. _If:
  3762.  
  3763.         Entry 
  3764.         def __argarray, di
  3765.         defwords _args, 20                              ; stores up to 10 arg entries
  3766.         def _notflag, 0000
  3767.         def _returnvalue
  3768.         def _usedportion, 0000
  3769.  
  3770. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3771. ;  type first few arguments
  3772. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3773.  
  3774.         mov cx, 5                                       ; # args to scan
  3775.         lea di, offset [ _args ][ bp ]                  ; pointer to arg store value
  3776.         push cx
  3777.         push di
  3778.  
  3779.         xor ax, ax
  3780.         add cx, cx                                      ; # ddef entries to clear
  3781.         rep stosw        
  3782.  
  3783.         pop bx
  3784.         pop cx
  3785.         mov di, word ptr [ __argarray ][ bp ]
  3786.  
  3787. _If_08:
  3788.         mov si, word ptr [ di ]                         ; get argument passed
  3789.         or si, si                                       ; no more args ?
  3790.         jz _If_16                                       ; quit typing -->
  3791.  
  3792.         mov word ptr [ bx. _argtext ], si               ; pointer to text
  3793.  
  3794.         push di
  3795.         push bx
  3796.         push cx
  3797.         mov di, offset RxDOS_IfOptions
  3798.         call CmndLookup                                 ; lookup command
  3799.         mov ax, bx                                      ; save type
  3800.  
  3801.         pop cx
  3802.         pop bx
  3803.         pop di
  3804.         jc _If_12
  3805.         mov word ptr [ bx. _argtype ], ax               ; value returned from lookup
  3806.         
  3807. _If_12:
  3808.         add bx, 4                                       ; lookup first three args
  3809.         add di, 2                                       ; lookup first three args
  3810.         loop _If_08             
  3811.  
  3812. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3813. ;  see if == special case
  3814. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3815.  
  3816. _If_16:
  3817.         lea bx, offset [ _args ][ bp ]                  ; pointer to arg 
  3818.         cmp word ptr [ bx. _argtype ], IF_NOT           ; not argument ?
  3819.         jnz _If_20                                      ; no -->
  3820.         add bx, 4                                       ; then we'll use next as base
  3821.         storarg _notflag, -1                            ; if not
  3822.  
  3823. _If_20:
  3824.         cmp word ptr [ bx. _argtype ], IF_ERRORLEVEL
  3825.         ifz _ifErrorLevel
  3826.         cmp word ptr [ bx. _argtype ], IF_EXIST
  3827.         ifz _ifExist
  3828.  
  3829.         mov si, word ptr [ bx + 4 ][ _argtext ]         ; next arg
  3830.         or si, si                                       ; no text ?
  3831.         jz _IfSyntaxError                               ; syntax error -->
  3832.  
  3833.         cmp word ptr [ si ], "=="                       ; equals case ?
  3834.         jz _ifEquals
  3835.  
  3836. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3837. ;  syntax error
  3838. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3839.  
  3840. _IfSyntaxError:
  3841.         mov dx, offset CmndError_SyntaxError
  3842.         call DisplayErrorMessage                        ; display message
  3843.         Return
  3844.         
  3845. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3846. ;  if equals
  3847. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3848.  
  3849. _ifEquals:
  3850.     mov si, word ptr [ bx     ][ _argtext ]
  3851.         or si, si                                       ; arg before =='s 
  3852.         jz _IfSyntaxError                               ; if syntax error -->
  3853.  
  3854.     mov di, word ptr [ bx + 12][ _argtext ]
  3855.         or di, di                                       ; arg after =='s 
  3856.         jz _IfSyntaxError                               ; if syntax error -->
  3857.  
  3858.     storarg _usedportion, di
  3859.  
  3860. _ifEquals_04:
  3861.         cmpsb                                           ; compare equals ?
  3862.         jnz _ifEquals_08                                ; not equal -->
  3863.         mov al, byte ptr [ di ]
  3864.         cmp al, '='                                     ; at end of arg ?
  3865.         jz _ifEquals_04
  3866.         cmp al, ' '                                     ; at end of arg ?
  3867.         jnz _ifEquals_04
  3868.  
  3869. _ifEquals_08:
  3870.         lahf                                            ; zer/not zero to ah
  3871.         xor ah, byte ptr [ _notflag ][ bp ]             ; toggle Not Equal Bit
  3872.         and ah, 01000000b                               ; not zero if logical continue
  3873.         jnz _ifTrue
  3874.  
  3875.         Return
  3876.  
  3877. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3878. ;  if errorlevel
  3879. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3880.  
  3881. _ifErrorLevel:
  3882.         Int21 GetReturnCode                             ; get return value
  3883.         and ax, 255                                     ; get previous return value
  3884.         storarg _returnvalue, ax
  3885.         
  3886.     mov si, word ptr [ bx + 4 ][ _argtext ]         ; get text pointer to next arg
  3887.     storarg _usedportion, si
  3888.         or si, si
  3889.         jz _IfSyntaxError                               ; if syntax error -->
  3890.  
  3891.         call _GetNumber                                 ; get expected number
  3892.         jc _IfSyntaxError                               ; if syntax error -->
  3893.         
  3894.         cmp ax, word ptr [ _returnvalue ][ bp ]         ; current >= return value ?
  3895.         lahf                                            ; zer/not zero to ah
  3896.         xor ah, byte ptr [ _notflag ][ bp ]             ; toggle Not Equal Bit
  3897.         and ah, 00000001b                               ; not zero if logical continue
  3898.         jz _ifTrue                                      ; do rest of line -->
  3899.         
  3900.         Return
  3901.         
  3902. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3903. ;  if exist
  3904. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3905.  
  3906. _ifExist:
  3907.  
  3908.         mov cx, ATTR_DIRECTORY
  3909.     mov dx, word ptr [ bx + 4 ][ _argtext ]         ; get text pointer to next arg
  3910.     storarg _usedportion, dx
  3911.         Int21 FindFirstFile                             ; does this file exist ?
  3912.  
  3913.         lahf                                            ; zer/not zero to ah
  3914.         xor ah, byte ptr [ _notflag ][ bp ]             ; toggle Not Equal Bit
  3915.         and ah, 00000001b                               ; not zero means not True
  3916.         jz _ifTrue                                      ; do rest of line -->
  3917.  
  3918.         Return
  3919.  
  3920. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3921. ;  if cond is true. execute command that follows
  3922. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3923.  
  3924. _ifTrue:
  3925.         getarg di, __argarray
  3926.     getarg dx, _usedportion                         ; used args
  3927.         sub di, 2
  3928.  
  3929. _ifTrue_08:
  3930.         inc di
  3931.         inc di
  3932.         cmp word ptr [ di ], 0000
  3933.         ifz _IfSyntaxError
  3934.         cmp word ptr [ di ], dx                         ; located used part of If ?
  3935.         jc _ifTrue_08                                   ; not yet -->
  3936.  
  3937.         inc di
  3938.         inc di
  3939.         call _executeCommandArray
  3940.         Return
  3941.  
  3942.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3943.         ;  Make Directory                                               ;
  3944.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3945.         ;                                                               ;
  3946.         ;  Usage:                                                       ;
  3947.         ;   ss:di  Arg Array                                            ;
  3948.         ;   ax     Number of arguments in array                         ;
  3949.         ;...............................................................;
  3950.  
  3951. _makeDir:
  3952.         
  3953.         call CheckOneArg                                ; see if 1 arg 
  3954.         jc _makeDir_32                                  ; if error -->
  3955.  
  3956. _makeDir_22:
  3957.         mov dx, word ptr [ di ]                         ; point to filename arg
  3958.         Int21 CreateSubdirectory                        ; try changing dir
  3959.         jnc _makeDir_32                                 ; if valid -->
  3960.  
  3961.         cmp ax, errAccessDenied                         ; access denined ?
  3962.         jnz _makeDir_26                                 ; show other errors -->
  3963.  
  3964.         mov dx, offset CmndError_SubDirAlreadyExists
  3965.         call DisplayErrorMessage
  3966.         jmp short _makeDir_32
  3967.  
  3968. _makeDir_26:
  3969.         call DisplayError                               ; if error
  3970.  
  3971. _makeDir_32:
  3972.         ret
  3973.  
  3974.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  3975.         ;  Path                                                         ;
  3976.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  3977.         ;                                                               ;
  3978.         ;  Usage:                                                       ;
  3979.         ;   ss:di  Arg Array                                            ;
  3980.         ;   ax     Number of arguments in array                         ;
  3981.         ;...............................................................;
  3982.  
  3983. _Path:
  3984.  
  3985.         Entry
  3986.         def __argarray, di
  3987.         def _newPathArg
  3988.         def _pathArgBeg
  3989.         def _pathEndPtr, 0000
  3990.  
  3991. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3992. ;  bypass initial = sign 
  3993. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3994.  
  3995. _Path_04:
  3996.         mov si, word ptr [ di ]
  3997.         or si, si
  3998.         jz _Path_06
  3999.  
  4000.         cmp byte ptr [ si ], '='
  4001.         jnz _Path_06
  4002.  
  4003.         inc di
  4004.         inc di
  4005.         jmp _Path_04
  4006.  
  4007. _Path_06:
  4008.         storarg _newPathArg, si
  4009.  
  4010. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4011. ;  locate current path arg, if any.
  4012. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4013.  
  4014.         mov si, offset RxDOS_PathSpec                   ; locate PATH=
  4015.         call searchEnvVariable                          ; env variable located ?
  4016.         jz _Path_08                                     ; if arg located -->
  4017.         storarg _pathEndPtr, di                         ; else this points to end
  4018.         xor di, di                                      ; say not found
  4019.  
  4020. _Path_08:
  4021.         storarg _pathArgBeg, di
  4022.  
  4023. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4024. ;  if no command given, type out current path value
  4025. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4026.  
  4027.         getarg si, _newPathArg
  4028.         or si, si                                       ; no args passed ?
  4029.         jnz _Path_16                                    ; yes, go update path -->
  4030.  
  4031.         getarg dx, _pathArgBeg
  4032.         or dx, dx                                       ; if arg passed ,
  4033.         jz _Path_14                                     ; else, display NoPath
  4034.  
  4035.         push es
  4036.         mov es, word ptr [ _EnvSegment ]
  4037.         call DisplayLine                                ; show current path
  4038.         call CRLF                                       ; cr/lf
  4039.         pop es
  4040.         Return
  4041.  
  4042. _Path_14:
  4043.         mov dx, offset CmndError_NoPath
  4044.         call DisplayLine                                ; show current path
  4045.         Return
  4046.         
  4047. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4048. ;  else, set path
  4049. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4050.  
  4051. _Path_16:
  4052.         push si                                         ; env string to add
  4053.         getarg di, _pathEndPtr                          ; get pointer to end
  4054.         getarg dx, _pathArgBeg                          ; restore arg to path
  4055.         or dx, dx                                       ; was any found ?
  4056.         jz _Path_24                                     ; no, no need to delete -->
  4057.  
  4058.         mov di, dx
  4059.         call deleteEnvVariable
  4060.  
  4061. _Path_24:
  4062.         mov si, offset RxDOS_PathSpec                   ; locate PATH=
  4063.         call insertEnvVariable
  4064.  
  4065.         dec di
  4066.         pop si
  4067.         call insertEnvVariable
  4068.         Return
  4069.  
  4070.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4071.         ;  Pause                                                        ;
  4072.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4073.         ;                                                               ;
  4074.         ;  Usage:                                                       ;
  4075.         ;   ss:di  Arg Array                                            ;
  4076.         ;   ax     Number of arguments in array                         ;
  4077.         ;...............................................................;
  4078.  
  4079. _Pause:
  4080.         mov dx, offset _PressAnyKeyToContinue
  4081.         Int21 PrintString
  4082.         Int21 ClearBufferedKeyboardInput, KeyboardInput
  4083.  
  4084.         call CRLF
  4085.         ret
  4086.  
  4087.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4088.         ;  Remark (Rem )                                                ;
  4089.         ;...............................................................;
  4090.  
  4091. _Rem:
  4092.         ret                                             ; do nothing
  4093.  
  4094.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4095.         ;  Remove Directory                                             ;
  4096.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4097.         ;                                                               ;
  4098.         ;  Usage:                                                       ;
  4099.         ;   ss:di  Arg Array                                            ;
  4100.         ;   ax     Number of arguments in array                         ;
  4101.         ;...............................................................;
  4102.  
  4103. _RemDir:
  4104.         
  4105.         call CheckOneArg                                ; see if 1 arg 
  4106.         jc _removeDir_32                                ; if error -->
  4107.  
  4108.         mov dx, word ptr [ di ]                         ; point to filename arg
  4109.         Int21 RemoveSubdirectory                        ; try command
  4110.         jnc _removeDir_32                               ; if valid -->
  4111.  
  4112.         call DisplayError                               ; if error
  4113.  
  4114. _removeDir_32:
  4115.         ret
  4116.  
  4117.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4118.         ;  SET                                                          ;
  4119.         ;  SET variable=                                                ;
  4120.         ;  SET variable=string                                          ;
  4121.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4122.         ;                                                               ;
  4123.         ;  Display, set or remove environment variable.                 ;
  4124.         ;...............................................................;
  4125.  
  4126. _Set:
  4127.  
  4128.         Entry
  4129.         def __argarray, di
  4130.  
  4131.         call CountArgs
  4132.         or ax, ax                                       ; if no args 
  4133.         jnz _SetEnvVariable                             ; set/ clear env variable -->
  4134.  
  4135. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4136. ;  display environment variables
  4137. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4138.  
  4139. _SetDisplay:
  4140.         xor si, si
  4141.         mov es, word ptr [ _EnvSegment ]
  4142.  
  4143. _SetDisplay_08:
  4144.         cmp byte ptr es:[ si ], 00
  4145.         jz _SetDisplayReturn
  4146.         cmp byte ptr es:[ si ], ';'                     ; if comment,
  4147.         jz _SetDisplay_12                               ; skip -->
  4148.  
  4149.         mov dx, si
  4150.         call DisplayLine
  4151.         call CRLF
  4152.  
  4153. _SetDisplay_12:
  4154.         inc si                                          ; scan to end of env string
  4155.         cmp byte ptr es:[ si - 1 ], 00
  4156.         jnz _SetDisplay_12
  4157.         jmp _SetDisplay_08 
  4158.  
  4159. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4160. ;  set/clear environment variable
  4161. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4162.  
  4163. _SetEnvVariable:
  4164.  
  4165.         mov di, word ptr [ __argarray ][ bp ]
  4166.         mov si, word ptr [ di ]                         ; get lead arg
  4167.  
  4168. _SetEnvVariable_08:
  4169.         inc si
  4170.         cmp byte ptr [ si-1 ], '='                      ; line contains a break ?
  4171.         jz _SetEnvVariable_12                           ; yes -->
  4172.         cmp byte ptr [ si-1 ], 00                       ; end of string ?
  4173.         jnz _SetEnvVariable_08                          ; not yet -->
  4174.  
  4175.         mov dx, offset CmndError_SyntaxError
  4176.         call DisplayErrorMessage                        ; display message
  4177.         Return
  4178.  
  4179. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4180. ;  upper case up to '='
  4181. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4182.  
  4183. _SetEnvVariable_12:
  4184.         mov si, word ptr [ di ]                         ; get lead arg
  4185.  
  4186. _SetEnvVariable_14:
  4187.         mov al, byte ptr [ si ]
  4188.         or al, al
  4189.         jz _SetEnvVariable_16
  4190.         cmp al, '='
  4191.         jz _SetEnvVariable_16
  4192.  
  4193.         call _upperCase
  4194.         mov byte ptr [ si ], al
  4195.         inc si
  4196.         jmp _SetEnvVariable_14
  4197.  
  4198. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4199. ;  search/ delete
  4200. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4201.  
  4202. _SetEnvVariable_16:
  4203.         mov si, word ptr [ di ]                         ; get lead arg
  4204.         call searchEnvVariable                          ; env variable located ?
  4205.         jnz _SetEnvVariable_18                          ; not found -->
  4206.  
  4207.         call deleteEnvVariable                          ; delete env variable
  4208.         
  4209. _SetEnvVariable_18:
  4210.         mov si, word ptr [ __argarray ][ bp ]
  4211.         mov si, word ptr [ si ]                         ; get lead arg
  4212.         call insertEnvVariable                          ; insert at end
  4213.  
  4214. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4215. ;  return
  4216. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4217.  
  4218. _SetDisplayReturn:
  4219.         Return
  4220.  
  4221.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4222.         ;  Shift                                                        ;
  4223.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4224.         ;                                                               ;
  4225.         ;  No parameters expected                                       ;
  4226.         ;...............................................................;
  4227.  
  4228. _Shift:
  4229.  
  4230.         mov si, offset ( RxDOS_BatchFile. batchArgPtrs ); copy args down
  4231.         mov cx, word ptr [ RxDOS_BatchFile. batchNumArgs ]
  4232.         or cx, cx
  4233.         jz _shift_32                                    ; if no arguments -->
  4234.  
  4235. _shift_08:
  4236.         mov ax, word ptr [ si + 2 ]
  4237.         mov word ptr [ si ], ax                         ; shift arg down
  4238.         add si, 2                                       ; point to next arg
  4239.         loop _shift_08                                  ; loop through all args
  4240.  
  4241.         dec word ptr [ RxDOS_BatchFile. batchNumArgs ]  ; decr # args
  4242.  
  4243. _shift_32:
  4244.         mov word ptr [ si ], 0000                       ; null out last arg
  4245.         ret
  4246.  
  4247.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4248.         ;  Truename [ anypath ]                                         ;
  4249.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4250.         ;                                                               ;
  4251.         ;  Displays the DOS expanded filename.                          ;
  4252.         ;                                                               ;
  4253.         ;...............................................................;
  4254.  
  4255. _Truename:
  4256.  
  4257.         Entry
  4258.         defbytes _buffer, 128
  4259.  
  4260.         call CheckOptOneArg                             ; should have an arg
  4261.         jc _truename_36                                 ; error -->
  4262.  
  4263.         mov si, word ptr [ di ]                         ; get argument passed
  4264.         lea di, offset [ _buffer ][ bp ]
  4265.         Int21 GetActualFileName
  4266.  
  4267.         lea dx, offset [ _buffer ][ bp ]
  4268.         call DisplayLine                                ; print line
  4269.  
  4270. _truename_36:
  4271.         Return
  4272.  
  4273.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4274.         ;  Type filename                                                ;
  4275.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4276.         ;                                                               ;
  4277.         ;  Unlike MSDOS, TYPE will permit both the use of the pause /p  ;
  4278.         ;  switch and wild card characters in a name.                   ;
  4279.         ;                                                               ;
  4280.         ;...............................................................;
  4281.  
  4282. _Type:
  4283.  
  4284.         Entry
  4285.         def __argarray, di
  4286.         def _handle
  4287.         defbytes _buffer, 130
  4288.  
  4289.         mov cx, 0001                                    ; at least one arg
  4290.         mov dx, 0999                                    ; unlimitd number of args
  4291.         mov bx, offset _TypeSwitches
  4292.         call PreProcessCmndLine                         ; process switches
  4293.         jc _TypeReturn                                  ; if error -->
  4294.  
  4295.         mov ax, word ptr [ _TypePauseSwitch. swFlags ]
  4296.         call setPagingMode
  4297.  
  4298. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4299. ;  get next argument
  4300. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4301.  
  4302. _TypeNext:
  4303.         mov di, word ptr [ __argarray ][ bp ]
  4304.         add word ptr [ __argarray ][ bp ], 2
  4305.         mov dx, word ptr [ di ]
  4306.         or dx, dx                                       ; any more args ?
  4307.         jz _TypeReturn                                  ; if no more -->
  4308.         
  4309.         xor cx, cx
  4310.         Int21 findFirstFile                             ; filename found for arg ?
  4311.         jnc _TypeOpenFile                               ; no, go to next -->
  4312.  
  4313.         push dx
  4314.         mov dx, offset _TypeCannotFind
  4315.         call DisplayLine
  4316.  
  4317.         pop dx
  4318.         call DisplayLine                                ; show arg
  4319.         jmp _TypeNext
  4320.  
  4321. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4322. ;  open and print
  4323. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4324.  
  4325. _TypeOpenFile:
  4326.         mov dx, offset [ RxDOS_DTA. findFileName ]
  4327.         Int21 OpenFile, 0000                            ; open
  4328.         storarg _handle, ax
  4329.         jc _TypeNext
  4330.  
  4331.         call CRLF
  4332.  
  4333.         mov dx, offset [ RxDOS_DTA. findFileName ]
  4334.         call DisplayLine                                ; show arg
  4335.         call CRLF
  4336.  
  4337. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4338. ;  read and list
  4339. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4340.  
  4341. _TypeReadFile:
  4342.         mov cx, 128                                     ; how much to read
  4343.         getarg bx, _handle                              ; get handle
  4344.         lea dx, offset [ _buffer ][ bp ]                ; where to read
  4345.         Int21 ReadFile                                  ; read buffer
  4346.         jc _TypeCloseFile
  4347.         
  4348.         or ax, ax                                       ; at end of file ?
  4349.         jz _TypeCloseFile                               ; yes, go to next -->
  4350.  
  4351.         mov cx, ax                                      ; how much read
  4352.         lea dx, offset [ _buffer ][ bp ]                ; where to read
  4353.         call DisplayLineCount
  4354.         jmp _TypeReadFile
  4355.  
  4356. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4357. ;  close file
  4358. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4359.  
  4360. _TypeCloseFile:
  4361.         getarg bx, _handle                              ; get handle
  4362.         Int21 CloseFile
  4363.         call CRLF
  4364.  
  4365.         Int21 findNextFile                              ; more files ?
  4366.         jnc _TypeOpenFile                               ; yes, open file -->
  4367.         jmp _TypeNext                                   ; else go to next -->
  4368.  
  4369. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4370. ;  return
  4371. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4372.  
  4373. _TypeReturn:
  4374.         Return
  4375.  
  4376.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4377.         ;  Verify [ ON | OFF ]                                          ;
  4378.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4379.         ;                                                               ;
  4380.         ;  Sets, clears or reports on RxDOS disk verify parameters.     ;
  4381.         ;                                                               ;
  4382.         ;...............................................................;
  4383.  
  4384. _Verify:
  4385.  
  4386.         Entry
  4387.         ddef __argarray, ss, di
  4388.         def _args, ax
  4389.  
  4390.         call CheckOptOneArg                             ; see if 1 arg 
  4391.         jc _VerifyExit                                  ; if error -->
  4392.         
  4393.         or ax, ax                                       ; any arguments ?
  4394.         jz _VerifyPrintcurrent                          ; none, print current status -->
  4395.  
  4396. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4397. ;  test for On/ Off
  4398. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4399.  
  4400.         mov si, word ptr [ di ]                         ; get single argument
  4401.         mov di, offset RxDOS_OnOff
  4402.         call CmndLookup                                 ; lookup command
  4403.         jc _VerifyError                                 ; if not on/off, print line -->
  4404.  
  4405.         mov al, bl
  4406.         Int21 SetVerifySwitch                           ; set or clear verify switch
  4407.         Return
  4408.  
  4409. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4410. ;  must specify on or off
  4411. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4412.  
  4413. _VerifyError:
  4414.         mov dx, offset CmndError_MustSpecifyOnOff
  4415.         call DisplayErrorMessage
  4416.         Return
  4417.  
  4418. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4419. ;  print verify on/off value
  4420. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4421.  
  4422. _VerifyPrintcurrent:
  4423.         Int21 GetVerify
  4424.  
  4425.         mov bl, al
  4426.         xor bh, bh
  4427.         add bx, bx
  4428.         mov dx, word ptr [ _VerifyOptions ][ bx ]
  4429.         call DisplayLine
  4430.  
  4431. _VerifyExit:
  4432.         Return
  4433.  
  4434.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4435.         ;  Version                                                      ;
  4436.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4437.         ;                                                               ;
  4438.         ;  No parameters expected                                       ;
  4439.         ;...............................................................;
  4440.  
  4441. _Ver:
  4442.         call CheckNoArgs                                ; check for no arguments 
  4443.         jc _ver_32                                      ; if error -->
  4444.  
  4445.         call CRLF
  4446.  
  4447.         mov dx, offset RxDOS_Version
  4448.         call DisplayLine
  4449.  
  4450.         mov dx, offset RxDOS_VersionCopyright
  4451.         call DisplayLine
  4452.  
  4453. _ver_32:
  4454.         ret
  4455.  
  4456.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4457.         ;  Volume                                                       ;
  4458.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4459.         ;                                                               ;
  4460.         ;  Displays Volume Information                                  ;
  4461.         ;                                                               ;
  4462.         ;...............................................................;
  4463.  
  4464. _Vol:
  4465.  
  4466.         Entry
  4467.         def  _currdisk, 0000
  4468.         defbytes _printbuffer, 128
  4469.  
  4470.         Int21 CurrentDisk
  4471.         add al, 'A'                                     ; get drive
  4472.         mov byte ptr [ _currdisk ][ bp ], al            ; save current disk
  4473.  
  4474.         call checkOptOneArg
  4475.         jc _Vol_60                                      ; parameter is wrong -->
  4476.         jz _Vol_30                                      ; if no parameters -->
  4477.  
  4478.         mov si, word ptr [ di ]                         ; get pointer to first arg
  4479.         mov ax, word ptr [ si ]
  4480.         cmp ah, ':'                                     ; not a drive specification ?
  4481.         jnz _Vol_62                                     ; no -->
  4482.  
  4483.         call _lowerCase                                 ; disk id
  4484.         and ax, not 20h                                 ; upper case
  4485.  
  4486.         cmp al, 'Z'+1
  4487.         jnc _Vol_62
  4488.         cmp al, 'A'
  4489.         jc _Vol_62
  4490.  
  4491.         storarg _currdisk, ax                           ; save disk
  4492.  
  4493. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4494. ;  get disk volume
  4495. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4496.  
  4497. _Vol_30:
  4498.         mov bx, offset _Dir_NoVolumeLabel               ; assume no volume label
  4499.         call returnVolumeName
  4500.         jc _Vol_62                                      ; cannot open drive -->
  4501.         jnz _Vol_34                                     ; if no volume name -->
  4502.  
  4503.         push di                                         ; save vol label pointer
  4504.         mov bx, offset _Dir_VolumeLabel                 ; print statement format
  4505.  
  4506. _Vol_34:
  4507.         lea di, offset [ _currdisk ][ bp ]              ; pointer to current disk
  4508.         push di                                         ; current disk
  4509.         push bx                                         ; format
  4510.         lea di, offset [ _printbuffer ][ bp ]
  4511.         push di
  4512.         call _sprintf
  4513.         add sp, ax                                      ; # args passed
  4514.         call DisplayLine
  4515.  
  4516. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4517. ;  return
  4518. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4519.  
  4520. _Vol_60:
  4521.         Return
  4522.  
  4523. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4524. ;  drive specification error
  4525. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4526.  
  4527. _Vol_62:
  4528.         mov dx, offset CmndError_InvalidDrive
  4529.         call DisplayErrorMessage
  4530.         Return
  4531.  
  4532.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4533.         ;  Commands Not Supported                                       ;
  4534.         ;...............................................................;
  4535.  
  4536. _Chcp:
  4537. _Ctty:
  4538. _Loadhigh:
  4539.         mov dx, offset CmndError_NotSupportedInRxDOS
  4540.         call DisplayErrorMessage
  4541.         ret
  4542.  
  4543.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4544.         ;  Other Commands                                               ;
  4545.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4546.         ;                                                               ;
  4547.         ;                                                               ;
  4548.         ;                                                               ;
  4549.         ;...............................................................;
  4550.  
  4551. _Help:
  4552. _History:
  4553. _Move:
  4554.         mov dx, offset CmndError_NotSupportedYet
  4555.         call DisplayErrorMessage
  4556.         ret
  4557.  
  4558.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4559.         ;  Not A Valid Command                                          ;
  4560.         ;...............................................................;
  4561.  
  4562. _NotValidCommand:
  4563.         mov dx, offset CmndError_BadCommandOrFileName
  4564.         call DisplayErrorMessage
  4565.         ret
  4566.  
  4567.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4568.         ;  Exit (;** just a debug backdoor so far)                      ;
  4569.         ;...............................................................;
  4570.  
  4571. _Exit:
  4572.     int 3
  4573.  
  4574.         Int21 TerminateProgram, 00h
  4575.         ret 
  4576.  
  4577.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4578.         ;  Save Batch File Position                                     ;
  4579.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4580.         ;                                                               ;
  4581.         ;  Returns:                                                     ;
  4582.         ;   bx     batch file handle                                    ;
  4583.         ;   dx:ax  position in batch file                               ;
  4584.         ;...............................................................;
  4585.  
  4586. getBatchPosition:
  4587.  
  4588.         xor cx, cx
  4589.         xor dx, dx
  4590.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  4591.         Int21 MoveFilePointer, SEEK_CUR
  4592.         ret
  4593.  
  4594.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4595.         ;  Manage Stdin Input                                           ;
  4596.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4597.         ;                                                               ;
  4598.         ;  Usage:                                                       ;
  4599.         ;   ss:dx  buffer (pointer to max length)                       ;
  4600.         ;...............................................................;
  4601.  
  4602. _getStdinLine:
  4603.  
  4604.         Entry
  4605.         def _buffer, dx
  4606.  
  4607.         push di
  4608.         push bx
  4609.         push dx
  4610.  
  4611.         mov di, dx
  4612.         mov byte ptr [ bufActualLength ][ di ], 00
  4613.  
  4614.         mov bx, STDIN
  4615.         Int21 IoControl, 00h                            ; get stdin device data
  4616.         test dx, 80h                                    ; file or device ?
  4617.         jnz _getStdinLine_32                            ; device, just read directly -->
  4618.  
  4619. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4620. ;  read by character if file
  4621. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4622.  
  4623. _getStdinLine_08:
  4624.         mov di, word ptr [ _buffer ][ bp ]
  4625.         mov bl, byte ptr [ bufActualLength ][ di ]      ; store character into buffer
  4626.         xor bh, bh
  4627.         lea dx, offset [ bufData ][ di + bx ]           ; data address
  4628.  
  4629.         mov cx, 1
  4630.         mov bx, STDIN
  4631.         Int21 ReadFile                                  ; read character
  4632.         jc _getStdinLine_28
  4633.  
  4634.         or ax, ax                                       ; read anything ?
  4635.         jz _getStdinLine_28                             ; no, see if return -->
  4636.  
  4637.         mov di, word ptr [ _buffer ][ bp ]
  4638.         mov bl, byte ptr [ bufActualLength ][ di ]      ; store character into buffer
  4639.         xor bh, bh
  4640.  
  4641.         mov dl, byte ptr [ bufData ][ di + bx ]         ; get character 
  4642.         cmp dl, 'J'-40h                                 ; character lf ?
  4643.         jz _getStdinLine_08                             ; ignore lf -->
  4644.  
  4645.         push dx
  4646.         Int21 DisplayOutput                             ; echo character
  4647.  
  4648.         pop dx
  4649.         inc byte ptr [ bufActualLength ][ di ]          ; store character into buffer
  4650.         cmp dl, 'M'-40h                                 ; character cr ?
  4651.         jz _getStdinLine_34                             ; yes, end of input -->
  4652.  
  4653.         mov al, byte ptr [ bufActualLength ][ di ]      ; actual less than max ?
  4654.         cmp al, byte ptr [ bufMaxLength ][ di ]         ; get max
  4655.         jc _getStdinLine_08
  4656.         jmp short _getStdinLine_34
  4657.  
  4658. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4659. ;  end of file
  4660. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4661.  
  4662. _getStdinLine_28:
  4663.         mov di, word ptr [ _buffer ][ bp ]
  4664.         mov dl, byte ptr [ bufActualLength ][ di ]      ; store character into buffer
  4665.         or dl, dl                                       ; any characters ?
  4666.         jnz _getStdinLine_34                            ; yes, return -->
  4667.  
  4668. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4669. ;  cancel stdin
  4670. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4671.  
  4672.         mov ax, 1                                       ; this may have to change !
  4673.         mov bx, STDIN
  4674.         call _CloseRedirectedDevice
  4675.  
  4676. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4677. ;  read directly if device
  4678. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4679.  
  4680. _getStdinLine_32:
  4681.         pop dx                                          ; buffer address
  4682.         Int21 GetLine                                   ; read direct from device
  4683.  
  4684. _getStdinLine_34:
  4685.         getarg dx, _buffer
  4686.         pop bx
  4687.         pop di
  4688.         Return
  4689.  
  4690.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4691.         ;  Read Line                                                    ;
  4692.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4693.         ;                                                               ;
  4694.         ;  Usage:                                                       ;
  4695.         ;   ss:si  buffer (pointer to max length)                       ;
  4696.         ;   bx     file handle (null value means stdin )                ;
  4697.         ;   al     echo status                                          ;
  4698.         ;...............................................................;
  4699.  
  4700. _ReadLine:
  4701.  
  4702.         Entry
  4703.         def _Handle, bx
  4704.         ddef _buffer, ss, si
  4705.  
  4706.         or bx, bx                                       ; process from batch file ?
  4707.         jz _ReadLine_08                                 ; no, read from console -->
  4708.         call _ReadBatch                                 ; else read batch file
  4709.         jmp short _ReadLine_26
  4710.  
  4711. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4712. ;  read from keyboard
  4713. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4714.  
  4715. _ReadLine_08:
  4716.         call DisplayPrompt                              ; display prompt
  4717.  
  4718.         mov dx, word ptr [ _buffer. _pointer ][ bp ]
  4719.         call _getStdinLine                              ; read buffer
  4720.  
  4721.         call CRLF
  4722.  
  4723. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4724. ;  return
  4725. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4726.  
  4727. _ReadLine_26:
  4728.         mov si, word ptr [ _buffer. _pointer ][ bp ]
  4729.         mov al, byte ptr [ bufActualLength ][ si ]
  4730.         and ax, 255                                     ; actual length
  4731.         Return
  4732.  
  4733.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4734.         ;  Read Batch Line                                              ;
  4735.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4736.         ;                                                               ;
  4737.         ;  Usage:                                                       ;
  4738.         ;   ss:si  buffer (pointer to max length)                       ;
  4739.         ;   bx     file handle (null value means stdin )                ;
  4740.         ;   al     echo status                                          ;
  4741.         ;...............................................................;
  4742.  
  4743. _ReadBatch:
  4744.  
  4745.         Entry
  4746.         def  _bytesRead
  4747.         def  _echoline, ax
  4748.         def  _Handle, bx
  4749.         ddef _buffer, ss, si
  4750.  
  4751.         add si, bufData                                 ; offset to data
  4752.         ddef _bufferData, ss, si
  4753.  
  4754. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4755. ;  read line
  4756. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4757.  
  4758.         mov cx, sizeCmdLine
  4759.         mov dx, word ptr [ _bufferData. _pointer ][ bp ]; where to read
  4760.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  4761.  
  4762.         call ReadBatchLine
  4763.         mov word ptr [ _bytesRead ][ bp ], ax
  4764.         jnz _ReadBatch_08                               ; no -->
  4765.  
  4766.         call _EndCall                                   ; end batch file call
  4767.  
  4768.         xor ax, ax                                      ; return zero bytes
  4769.         mov di, word ptr [ _buffer. _pointer ][ bp ]    ; buffer address
  4770.         mov byte ptr [ bufActualLength ][ di ], al
  4771.         Return
  4772.  
  4773. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4774. ;  trim line to carriage return
  4775. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4776.  
  4777. _ReadBatch_08:
  4778.         mov di, word ptr [ _buffer. _pointer ][ bp ]    ; buffer address
  4779.         mov byte ptr [ bufActualLength ][ di ], al
  4780.  
  4781. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4782. ;  perform variable replacement
  4783. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4784.  
  4785. _ReadBatch_20:
  4786.         mov bx, word ptr [ _bytesRead ][ bp ]
  4787.         mov si, word ptr [ _bufferData. _pointer ][ bp ]; buffer address
  4788.         mov byte ptr [ si+bx ], 00
  4789.         call ReplaceTempVariables                       ; replace %n variables
  4790.  
  4791.         mov si, word ptr [ _buffer. _pointer ][ bp ]    ; buffer address
  4792.         mov byte ptr [ bufActualLength ][ si ], cl
  4793.  
  4794. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4795. ;  echo enabled ?
  4796. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4797.  
  4798.         cmp byte ptr [ _echoLine ][ bp ], 00
  4799.         jz _ReadBatch_32                                ; echo is off -->
  4800.  
  4801.         mov cx, ax                                      ; length of line
  4802.         mov di, word ptr [ _bufferData. _pointer ][ bp ]; buffer address
  4803.  
  4804. _ReadBatch_24:
  4805.         cmp byte ptr [ di ], '@'                        ; line starts with @ ?
  4806.         jz _ReadBatch_32                                ; yes, no echo -->
  4807.         cmp byte ptr [ di ], ' '                        ; still in white space ?
  4808.         jnz _ReadBatch_26                               ; no, echo line -->
  4809.         inc di
  4810.         loop  _ReadBatch_24
  4811.  
  4812. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4813. ;  echo this line
  4814. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4815.  
  4816. _ReadBatch_26:
  4817.         call DisplayPrompt                              ; display prompt
  4818.  
  4819.         mov dx, di
  4820.         call DisplayLine                                ; echo line
  4821.         call CRLF
  4822.  
  4823. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4824. ;  return
  4825. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4826.  
  4827. _ReadBatch_32:
  4828.         mov di, word ptr [ _buffer. _pointer ][ bp ]    ; buffer address
  4829.         mov ax, word ptr [ _bytesRead ][ bp ]
  4830.         or di, di                                       ; data always returned
  4831.         Return
  4832.  
  4833.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4834.         ;  Read Batch Line                                              ;
  4835.         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  4836.         ;                                                               ;
  4837.         ;  Returns:                                                     ;
  4838.         ;   bx     batch file handle                                    ;
  4839.         ;   dx     line buffer address                                  ;
  4840.         ;...............................................................;
  4841.  
  4842.  
  4843. ReadBatchLine:
  4844.  
  4845.         Entry
  4846.         def  _Handle, bx
  4847.         def  _lineBuffer, dx
  4848.         def  _bytesRead, 0000
  4849.         ddef _filePosition
  4850.         defbytes _tempbuffer, 2
  4851.  
  4852. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4853. ;  get current position in file
  4854. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4855.  
  4856.         xor cx, cx
  4857.         xor dx, dx
  4858.         Int21 MoveFilePointer, SEEK_CUR
  4859.         mov word ptr [ _FilePosition. _low  ][ bp ], ax
  4860.         mov word ptr [ _FilePosition. _high ][ bp ], dx ; save current position
  4861.  
  4862. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4863. ;  get current position in file
  4864. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4865.  
  4866.         getarg si, _lineBuffer
  4867.         mov byte ptr [ si ], 00                         ; set null terminator at beg
  4868.  
  4869.         getarg bx, _Handle
  4870.         mov cx, sizeCmdLine
  4871.         getarg dx, _lineBuffer                          ; where to read batch file
  4872.         Int21 ReadFile                                  ; read
  4873.         jc ReadBatchLine_36                             ; if error -->
  4874.         mov word ptr [ _bytesRead ][ bp ], ax
  4875.         or ax, ax                                       ; end of batch file ?
  4876.         jz ReadBatchLine_36                             ; yes -->
  4877.  
  4878. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4879. ;  trim line to carriage return
  4880. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4881.  
  4882.         mov cx, ax                                      ; scan line 
  4883.         getarg di, _lineBuffer                          ; where to read batch file
  4884.  
  4885.         mov al, 'M'-40h
  4886.         repnz scasb                                     ; scan for cr
  4887.         jz ReadBatchLine_20                             ; carriage return found -->
  4888.  
  4889. ReadBatchLine_12:
  4890.         mov cx, 1
  4891.         lea dx, offset [ _tempbuffer ][ bp ]            ; scan char by character till cr
  4892.         Int21 ReadFile                                  ; read
  4893.         jc ReadBatchLine_36                             ; if error -->
  4894.         or ax, ax                                       ; end of file ?
  4895.         jz ReadBatchLine_36                             ; yes -->
  4896.  
  4897.         cmp byte ptr [ _tempbuffer ][ bp ], 'M'- 40h    ; carriage return ?
  4898.         jnz ReadBatchLine_12                            ; no -->
  4899.         jmp short ReadBatchLine_30                      ; process line a bit -->
  4900.  
  4901. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4902. ;  position line immediately after cr
  4903. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4904.  
  4905. ReadBatchLine_20:
  4906.         mov ax, word ptr [ _bytesRead ][ bp ]
  4907.         sub ax, cx
  4908.         push ax
  4909.  
  4910.         cmp byte ptr [ di ], 'J'-40h
  4911.         jnz ReadBatchLine_22                            ; if line feed doesn't follow -->
  4912.         inc ax                                          ; account for lf
  4913.  
  4914. ReadBatchLine_22:
  4915.         mov dx, word ptr [ _FilePosition. _low  ][ bp ]
  4916.         mov cx, word ptr [ _FilePosition. _high ][ bp ] ; orig position
  4917.         add dx, ax
  4918.         adc cx, 0000
  4919.  
  4920.         getarg bx, _Handle
  4921.         Int21 MoveFilePointer, SEEK_BEG                 ; get current position
  4922.  
  4923.         pop ax
  4924.         dec ax                                          ; don't include cr
  4925.         mov word ptr [ _bytesRead      ][ bp ], ax      ; bytes read
  4926.  
  4927. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4928. ;  does line begin with a line feed ?
  4929. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4930.  
  4931. ReadBatchLine_30:
  4932.         getarg di, _lineBuffer
  4933.         cmp byte ptr [ di ], 'J'-40h
  4934.         jnz ReadBatchLine_32                            ; no -->
  4935.  
  4936.         getarg cx, _bytesRead
  4937.         mov si, di
  4938.         inc si
  4939.         rep movsb                                       ; delete
  4940.  
  4941.         dec word ptr [ _bytesRead ][ bp ]
  4942.  
  4943. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4944. ;  place null terminator at end
  4945. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4946.  
  4947. ReadBatchLine_32:
  4948.         getarg bx, _bytesRead
  4949.         getarg si, _lineBuffer
  4950.         mov byte ptr [ si+bx ], 00                      ; set null terminator at end 
  4951.  
  4952.         mov ax, bx
  4953.         or si, si                                       ; nz means valid return
  4954.         Return
  4955.  
  4956. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4957. ;  end of file or error
  4958. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4959.  
  4960. ReadBatchLine_36:
  4961.         xor ax, ax
  4962.         Return
  4963.  
  4964.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  4965.         ;  Command Shell Start                                          ;
  4966.         ;...............................................................;
  4967.  
  4968. CommandBegin:
  4969.  
  4970.         cli
  4971.         mov ax, cs
  4972.         mov ds, ax
  4973.         mov es, ax
  4974.         mov ss, ax
  4975.         mov sp, offset RxDOS_CmdStack
  4976.  
  4977.         sti
  4978.         cld
  4979.  
  4980.         mov byte ptr [ _EchoStatus ], TRUE              ; echo is ON
  4981.         mov word ptr [ RxDOS_BatchFile. batchNumArgs ], 0000  ; no args
  4982.  
  4983. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4984. ;  initialize stack frame
  4985. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4986.  
  4987.         Entry
  4988.         defbytes _cmdline, sizeCmdLineStruct
  4989.         defbytes _SaveBatchInfo, sizeBATCH_ARGS         ;  previous batch file 
  4990.  
  4991.         mov word ptr [ RxDOS_PrevStackFrame ], sp       ; current stack frame
  4992.  
  4993.         mov si, offset RxDOS_BatchFile
  4994.         mov di, word ptr [ RxDOS_PrevStackFrame ]
  4995.         mov cx, sizeBATCH_ARGS
  4996.         rep movsb                                       ; copy current args to save area
  4997.  
  4998. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4999. ;  get env, psp addresses
  5000. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5001.  
  5002.         Int21 GetPSPAddress
  5003.         mov word ptr [ _PSPSegment ], bx
  5004.  
  5005.         mov es, bx                                      ; set PSP address
  5006.         mov bx, word ptr es:[ pspEnvironment ]          ; get seg of Environment
  5007.         mov word ptr [ _EnvSegment ], bx
  5008.  
  5009.         dec bx                                          ; locate Mem Control Block
  5010.         mov es, bx                                      ; point to mem block
  5011.         mov bx, word ptr es:[ _memAlloc ]               ; allocation in paras of env block
  5012.         shl bx, 1
  5013.         shl bx, 1
  5014.         shl bx, 1
  5015.         shl bx, 1                                       ; conv paras to segs
  5016.         mov word ptr [ _EnvSize ], bx                   ; save env size
  5017.  
  5018. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5019. ;  set DTA
  5020. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5021.  
  5022.         Int21 GetDTA
  5023.         mov word ptr [ RxDOS_OrigDTA. _segment ], es
  5024.         mov word ptr [ RxDOS_OrigDTA. _pointer ], bx
  5025.  
  5026.         currSegment es
  5027.         mov dx, offset RxDOS_DTA
  5028.         Int21 SetDTA                                    ; set new disk transfer address
  5029.  
  5030. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5031. ;  init screen
  5032. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5033.  
  5034.         call PhysClearScreen                            ; start with a clear screen
  5035.  
  5036.         mov dx, offset RxDOS_Version
  5037.         call DisplayLine                                ; print startup version
  5038.  
  5039.         mov dx, offset RxDOS_VersionCopyright
  5040.         call DisplayLine                                ; print startup version
  5041.  
  5042. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5043. ;  basic command loop
  5044. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5045.  
  5046. CommandInput:
  5047.         mov sp, word ptr [ RxDOS_PrevStackFrame ]       ; current stack frame
  5048.  
  5049.         lea si, offset [ _cmdline ][ bp ]
  5050.         mov byte ptr ss:[ si ], sizeCmdLine
  5051.         mov bx, word ptr [ RxDOS_BatchFile. batchFileHandle ]
  5052.         mov al, byte ptr [ _EchoStatus ]
  5053.         call _ReadLine
  5054.         jz CommandInput                                 ; no, redisplay prompt -->
  5055.  
  5056.         mov bx, ax
  5057.         lea si, offset [ _cmdline. bufActualLength ][ bp ]
  5058.         mov byte ptr ss:[ si + bx + 1 ], 00             ; null terminate string
  5059.         Int2E
  5060.         jmp CommandInput   
  5061.  
  5062.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5063.         ;  Internal Commands                                            ;
  5064.         ;...............................................................;
  5065.  
  5066.         Even
  5067.  
  5068. RxDOS_InternalCommands:
  5069.  
  5070.         Cmnd _ChangeDir,        'cd'                    ; 
  5071.         Cmnd _ChangeDir,        'chdir'                 ; 
  5072.         Cmnd _MakeDir,          'md'                    ; 
  5073.         Cmnd _MakeDir,          'mkdir'                 ; 
  5074.         Cmnd _RemDir,           'rd'                    ; 
  5075.         Cmnd _RemDir,           'rmdir'                 ; 
  5076.  
  5077.         Cmnd _Break,            'break'                 ;
  5078.         Cmnd _Call,             'call'                  ; 
  5079.         Cmnd _Chcp,             'chcp'                  ; 
  5080.         Cmnd _Cls,              'cls'                   ; 
  5081.         Cmnd _Copy,             'copy'                  ; *
  5082.         Cmnd _Ctty,             'ctty'                  ; 
  5083.         Cmnd _Date,             'date'                  ;
  5084.         Cmnd _Delete,           'del'                   ; 
  5085.         Cmnd _Dir,              'dir'                   ; 
  5086.         Cmnd _Echo,             'echo'                  ; 
  5087.         Cmnd _Delete,           'erase'                 ; 
  5088.         Cmnd _Exit,             'exit'                  ; *
  5089.         Cmnd _For,              'for'                   ; 
  5090.         Cmnd _Goto,             'goto'                  ; 
  5091.         Cmnd _Help,             'help'                  ; *
  5092.         Cmnd _History,          'history'               ; * future feature
  5093.         Cmnd _History,          'his'                   ; * future feature
  5094.         Cmnd _If,               'if'                    ; 
  5095.         Cmnd _Loadhigh,         'lh'                    ; 
  5096.         Cmnd _Loadhigh,         'loadhigh'              ; 
  5097.         Cmnd _Move,             'move'                  ; * future feature
  5098.         Cmnd _Path,             'path'                  ;
  5099.         Cmnd _Pause,            'pause'                 ;
  5100.         Cmnd _Prompt,           'prompt'                ; 
  5101.         Cmnd _Rem,              'rem'                   ; 
  5102.         Cmnd _Rename,           'rename'                ; *
  5103.         Cmnd _Rename,           'ren'                   ; *
  5104.         Cmnd _Set,              'set'                   ;
  5105.         Cmnd _Shift,            'shift'                 ; 
  5106.         Cmnd _Time,             'time'                  ;
  5107.         Cmnd _Truename,         'truename'              ; 
  5108.         Cmnd _Type,             'type'                  ;
  5109.         Cmnd _Verify,           'verify'                ; 
  5110.         Cmnd _Ver,              'ver'                   ; 
  5111.         Cmnd _Vol,              'vol'                   ;
  5112.         dw -1
  5113.  
  5114.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5115.         ;  Environment Variables                                        ;
  5116.         ;...............................................................;
  5117.  
  5118. RxDOS_CommandSpec:              asciz 'COMSPEC='
  5119. RxDOS_DirSpec:                  asciz 'DIRCMD='
  5120. RxDOS_PathSpec:                 asciz 'PATH='
  5121. RxDOS_PromptSpec:               asciz 'PROMPT='
  5122. RxDOS_RxDOSSpec:                asciz 'RXDOS='
  5123. RxDOS_RxDOSSwitchSpec:          asciz 'SWITCH='
  5124.  
  5125.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5126.         ;  Execution Order                                              ;
  5127.         ;...............................................................;
  5128.  
  5129. RxDOS_ExecOrder:                asciz '.com'
  5130.                                 asciz '.exe'
  5131.                                 asciz '.bat'
  5132.                                 dw -1
  5133.  
  5134.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5135.         ;  On/Off Options                                               ;
  5136.         ;...............................................................;
  5137.  
  5138. RxDOS_OnOff:                    Cmnd 1,                 'on'
  5139.                                 Cmnd 0,                 'off'
  5140.                                 dw -1
  5141.  
  5142.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5143.         ;  If Options                                                   ;
  5144.         ;...............................................................;
  5145.  
  5146. RxDOS_IfOptions:                Cmnd IF_ERRORLEVEL,     'errorlevel'
  5147.                                 Cmnd IF_EXIST,          'exists'
  5148.                                 Cmnd IF_EXIST,          'exist'
  5149.                                 Cmnd IF_NOT,            'not'
  5150.                                 dw -1
  5151.  
  5152.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5153.         ;  For Options                                                  ;
  5154.         ;...............................................................;
  5155.  
  5156. RxDOS_ForArgs:                  Cmnd _IN,               'in'
  5157.                                 Cmnd _DO,               'do'
  5158.                                 dw -1
  5159.  
  5160.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5161.         ;  Version Prompt                                               ;
  5162.         ;...............................................................;
  5163.  
  5164. RxDOS_Version:                  db 'RxDOS Version 5.00', 0
  5165.  
  5166. RxDOS_VersionCopyright:         db 13, 10
  5167.                                 db '(c) Copyright 1990-1993 Api Software and Michael Podanoffsky', 13, 10
  5168.                                 db 'All rights reserved', 13, 10, 13, 10, 0
  5169.  
  5170.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5171.         ;  Error Table                                                  ;
  5172.         ;...............................................................;
  5173.  
  5174.         Even
  5175.  
  5176. CmndError_TextReferenceTable:
  5177.  
  5178.         dw 0                                            ; 0000
  5179.         dw 0                                            ; 0001
  5180.         dw CmndError_FileNotFound                       ; 0002
  5181.         dw CmndError_InvalidDirectory                   ; 0003
  5182.         dw 0                                            ; 0004
  5183.         dw CmndError_AccessDenied                       ; 0005
  5184.         dw 0                                            ; 0006
  5185.         dw 0                                            ; 0007
  5186.         dw 0                                            ; 0008
  5187.         dw 0                                            ; 0009
  5188.         dw 0                                            ; 0010
  5189.         dw 0                                            ; 0011
  5190.         dw 0                                            ; 0012
  5191.         dw 0                                            ; 0013
  5192.         dw 0                                            ; 0014
  5193.         dw 0                                            ; 0015
  5194.         dw CmndError_CurrentDirectory                   ; 0016
  5195.  
  5196. CmndError_RefTableEntries       equ ($ - CmndError_TextReferenceTable)/2
  5197.  
  5198.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5199.         ;  Error Messages                                               ;
  5200.         ;...............................................................;
  5201.  
  5202. CmndError_AccessDenied:         asciz 'access denied'
  5203. CmndError_BadCommandOrFileName: asciz 'bad command or file name could not be found'
  5204. CmndError_BadSwitch:            asciz 'bad switch - '
  5205. CmndError_CannotCopyUntoSelf:   asciz 'file cannot be copied unto itself'
  5206. CmndError_CannotCreateFile:     asciz 'cannot create destination file'
  5207. CmndError_ContentsLostBeforeCopy:asciz 'contents of file lost before copy'
  5208. CmndError_CurrentDirectory:     asciz 'cannot remove current directory'
  5209. CmndError_FileAlreadyExists:    asciz 'file not found or already exists'
  5210. CmndError_FileNotFound:         asciz 'file not found'  
  5211. CmndError_NoFilesFound:         asciz ' no files found', 13, 10
  5212. CmndError_InvalidDate:          asciz 'invalid date'
  5213. CmndError_InvalidDirectory:     asciz 'invalid directory'
  5214. CmndError_InvalidDrive:         asciz 'invalid drive'
  5215. CmndError_InvalidTime:          asciz 'invalid time'
  5216. CmndError_MustSpecifyOnOff:     asciz 'must specify ON or OFF'
  5217. CmndError_NotSupportedYet:      asciz 'command not supported yet !'
  5218. CmndError_NotSupportedInRxDOS:  asciz 'command not supported in RxDOS'
  5219. CmndError_FileNameMissing:      asciz 'file name missing'
  5220. CmndError_SubDirAlreadyExists:  asciz 'subdirectory already exists'
  5221. CmndError_SyntaxError:          asciz 'syntax error - use Help'
  5222. CmndError_TooManyParameters:    asciz 'too many parameters - '
  5223.  
  5224. CmndError_NoPath:               asciz 'no path'
  5225.  
  5226.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5227.         ;  Other Variables                                              ;
  5228.         ;...............................................................;
  5229.  
  5230. RxDOS_NewLine:                  db 13, 10, 0
  5231.  
  5232.                                 db 'c:'
  5233. RxDOS_RootDirectory             db '\*.*', 0            ; root directory
  5234. RxDOS_AllFiles                  db '*'                  ; combines to for *.*
  5235. RxDOS_AllExtensions             db '.*', 0
  5236.  
  5237.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5238.         ;  Echo/ Paging                                                 ;
  5239.         ;...............................................................;
  5240.  
  5241. _EchoStatus                     db TRUE                 ; echo is ON
  5242.  
  5243. PageLines                       db 00                   ; paging mode
  5244. LinesDisplayed                  dw 00                   ; # lines displayed, curr page
  5245.  
  5246.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5247.         ;  Prompt                                                       ;
  5248.         ;...............................................................;
  5249.  
  5250. RxDOS_DefaultPrompt             db '$n$g', 0
  5251. RxDOS_Prompt                    db '$n$g', 0, 128 dup(0)
  5252.  
  5253.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5254.         ;  Special Command Separators                                   ;
  5255.         ;...............................................................;
  5256.  
  5257. _CmndParse_Separators           db ' <>|[],+=()%', doubleQuote, singleQuote, 0
  5258. _SwitchChar                     db '/'                  ; switch character
  5259.  
  5260.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5261.         ;  Environment Location/ Size                                   ;
  5262.         ;...............................................................;
  5263.  
  5264. _PSPSegment                     dw 0                    ; PSP Segment Address
  5265. _EnvSegment                     dw 0                    ; Env Segment Address
  5266. _EnvSize                        dw 0                    ; Env Size (bytes)
  5267.  
  5268.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5269.         ;  Switches                                                     ;
  5270.         ;...............................................................;
  5271.  
  5272.         BATCH_ARGS struc
  5273.  
  5274. batchArgPtrs                    dw ?                    ; 0
  5275.                                 dw ?                    ; 1 arg pointers
  5276.                                 dw ?                    ; 2       .
  5277.                                 dw ?                    ; 3       .
  5278.                                 dw ?                    ; 4       .
  5279.                                 dw ?                    ; 5       .
  5280.                                 dw ?                    ; 6       .
  5281.                                 dw ?                    ; 7       .
  5282.                                 dw ?                    ; 8       .
  5283.                                 dw ?                    ; 9       .
  5284.  
  5285. batchNumArgs                    dw ?                    ; number of batch arguments
  5286. batchFileHandle                 dw ?                    ; batch file handle
  5287. batchFilePosition               dd ?                    ; batch file position
  5288.  
  5289. batchArgStore                   db 128 dup(0)
  5290.  
  5291.         BATCH_ARGS ends
  5292.  
  5293. sizeBATCH_ARGS                  equ size BATCH_ARGS
  5294.  
  5295.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5296.         ;  Batch File Arguments                                         ;
  5297.         ;...............................................................;
  5298.  
  5299. RxDOS_BatchFile                 db sizeBATCH_ARGS dup(0)
  5300. RxDOS_PrevStackFrame            dw 0                    ; end call stack frame
  5301. RxDOS_StackFrameNumEntries      dw 0                    ; number of entries in stack
  5302.  
  5303.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5304.         ;  Restore Original Parameters                                  ;
  5305.         ;...............................................................;
  5306.  
  5307. RxDOS_OrigDTA                   dd ?                    ; original DTA value
  5308.  
  5309.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5310.         ;  Type Switches                                                ;
  5311.         ;...............................................................;
  5312.  
  5313. _TypeSwitches:
  5314. _TypePauseSwitch:               Switch 'p', 0
  5315.                                 db -1
  5316.  
  5317. _TypeCannotFind:                asciz 'cannot find - '
  5318.  
  5319.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5320.         ;  Dir Switches                                                 ;
  5321.         ;...............................................................;
  5322.  
  5323. _DirSwitches:
  5324. _DirPauseSwitch:                Switch 'p', 0
  5325. _DirWideSwitch:                 Switch 'w', 0
  5326. _DirAttribSwitch:               Switch 'a', SW_LETTERCHOICE, SW_DIR_ATTRIB
  5327. _DirOrderSwitch:                Switch 'o', SW_LETTERCHOICE, SW_DIR_ORDER
  5328. _DirSubDirSwitch:               Switch 's', 0
  5329. _DirLowerCaseSwitch:            Switch 'l', 0
  5330. _DirBareSwitch:                 Switch 'b', 0
  5331.                                 db -1
  5332.  
  5333. SW_DIR_ATTRIB:                  db '-dnsra', 0
  5334. SW_DIR_ORDER:                   db '-negsd', 0
  5335.  
  5336. _Dir_NoVolumeLabel:             asciz ' Volume in drive %c has no label', 13, 10
  5337. _Dir_VolumeLabel:               asciz ' Volume in drive %c is %s', 13, 10
  5338. _Dir_VolumeSerialNumber:        asciz ' Volume Serial Number is %s', 13, 10
  5339. _Dir_DirectoryOf:               asciz ' Directory of %s', 13, 10, 13, 10
  5340. _Dir_Files:                     db    '    %5d file(s) %11,ld bytes', 13, 10
  5341.                                 db    '                  %11,ld bytes free', 13, 10, 0
  5342. _Dir_FileEntry:                 db    '%8s %3s %9ld %s  %s', 13, 10, 0
  5343. _Dir_DirEntry:                  db    '%8s %3s <DIR>     %s  %s', 13, 10, 0
  5344.  
  5345.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5346.         ;  Copy Messages                                                ;
  5347.         ;...............................................................;
  5348.  
  5349. _Copy_FilesCopied:              asciz ' %d file(s) copied'
  5350.  
  5351.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5352.         ;  Pause/ Continue                                              ;
  5353.         ;...............................................................;
  5354.  
  5355. _PressAnyKeyToContinue:         asciz 'Press any key to continue . . . $'
  5356. _Dir_Continuing:                asciz '(continuing %s)', 13, 10
  5357.  
  5358.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5359.         ;  Break Display Options                                        ;
  5360.         ;...............................................................;
  5361.  
  5362. _BreakOptions:                  dw _BreakIsOFF, _BreakIsON
  5363.  
  5364. _BreakIsOFF:                    asciz 'Break is OFF', 13, 10
  5365. _BreakIsON:                     asciz 'Break is ON', 13, 10
  5366.  
  5367.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5368.         ;  Echo Display Options                                         ;
  5369.         ;...............................................................;
  5370.  
  5371. _EchoOptions:                   dw _EchoIsOFF, _EchoIsON
  5372.  
  5373. _EchoIsOFF:                     asciz 'Echo is OFF', 13, 10
  5374. _EchoIsON:                      asciz 'Echo is ON', 13, 10
  5375.  
  5376.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5377.         ;  Verify Display Options                                       ;
  5378.         ;...............................................................;
  5379.  
  5380. _VerifyOptions:                 dw _VerifyIsOFF, _VerifyIsON
  5381.  
  5382. _VerifyIsOFF:                   asciz 'Verify is OFF', 13, 10
  5383. _VerifyIsON:                    asciz 'Verify is ON', 13, 10
  5384.  
  5385.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5386.         ;  Date Display Options                                         ;
  5387.         ;...............................................................;
  5388.  
  5389. _ShowCurrentDate:               asciz 'Current date is %s'
  5390. _PleaseEnterDate:               asciz 13, 10, 'Enter new date (mm-dd-yy): '
  5391.  
  5392.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5393.         ;  Time Display Options                                         ;
  5394.         ;...............................................................;
  5395.  
  5396. _ShowCurrentTime:               asciz 'Current time is %s'
  5397. _PleaseEnterTime:               asciz 13, 10, 'Enter new time: '
  5398.  
  5399. RxDOSIntl_DateTimeTable:        intldate 001, 'mm/dd/yyyy hh:mm:ss.00' ; USA
  5400.                                 intldate 002, 'yyyy-mm-dd HH:mm:ss,00' ; Canada-French
  5401.                                 intldate 003, 'dd/mm/yyyy hh:mm:ss.00' ; Latin America
  5402.                                 intldate 031, 'dd-mm-yyyy HH:mm:ss,00' ; Netherlands
  5403.                                 intldate 032, 'dd/mm/yyyy HH:mm:ss,00' ; Belgium
  5404.                                 intldate 033, 'dd.mm.yyyy HH:mm:ss,00' ; France
  5405.                                 intldate 034, 'dd/mm/yyyy HH:mm:ss,00' ; Spain
  5406.                                 intldate 036, 'yyyy-mm-dd HH:mm:ss,00' ; Hungary
  5407.                                 intldate 038, 'yyyy-mm-dd HH:mm:ss,00' ; Yugoslavia
  5408.                                 intldate 039, 'dd/mm/yyyy HH.mm.ss,00' ; Italy
  5409.                                 intldate 041, 'dd.mm.yyyy HH,mm,ss.00' ; Switzerland
  5410.                                 intldate 042, 'yyyy-mm-dd HH:mm:ss,00' ; Czechoslovakia
  5411.                                 intldate 044, 'dd/mm/yyyy HH:mm:ss.00' ; United Kingdom
  5412.                                 intldate 045, 'dd-mm-yyyy HH:mm:ss,00' ; Denmark
  5413.                                 intldate 046, 'yyyy-mm-dd HH.mm.ss,00' ; Sweden 
  5414.                                 intldate 047, 'dd.mm.yyyy HH:mm:ss,00' ; Norway
  5415.                                 intldate 048, 'yyyy-mm-dd HH:mm:ss,00' ; Hungary
  5416.                                 intldate 049, 'dd.mm.yyyy HH:mm:ss,00' ; Germany
  5417.                                 intldate 055, 'dd/mm/yyyy HH:mm:ss,00' ; Brazil
  5418.                                 intldate 061, 'dd/mm/yyyy HH:mm:ss.00' ; Intl English
  5419.                                 intldate 351, 'dd-mm-yyyy HH:mm:ss,00' ; Portugal
  5420.                                 intldate 358, 'dd.mm.yyyy HH.mm.ss,00' ; Finland
  5421.                                 dw -1
  5422.  
  5423. RxDOSIntl_TimeTemplate          db 'hh:mm:ss.00', 0
  5424. RxDOSIntl_DateTemplate          db 'www mm/dd/yyyy', 0              ; USA
  5425.  
  5426. RxDOSIntl_DayOfWeek             db 'SunMonTueWedThuFriSat', 0
  5427.  
  5428.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5429.         ;  Disk Transfer Address                                        ;
  5430.         ;...............................................................;
  5431.  
  5432.                               even  
  5433. RxDOS_DTA:                      db 128 dup(' ')
  5434.  
  5435.         ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
  5436.         ;  Command Shell Stack                                          ;
  5437.         ;...............................................................;
  5438.  
  5439.                               even  
  5440.                                 db 256 dup('RxDOSCMD')  ; 2k
  5441. RxDOS_CmdStack                  dw 0
  5442.  
  5443. RxDOSCMD                        ENDS
  5444.                                 END  CommandBegin
  5445.